Fix bug 298320: when showing a prompt via nsIPromptService, make sure that the tab from which the prompt originates is brought to the front. r=josh

This commit is contained in:
smfr%smfr.org 2005-06-29 01:25:35 +00:00
parent 734a842fd9
commit 28c0e14fe4
9 changed files with 194 additions and 104 deletions

View File

@ -275,6 +275,9 @@ typedef enum
- (void)closeBrowserWindow:(BrowserWrapper*)inBrowser;
- (void)willShowPromptForBrowser:(BrowserWrapper*)inBrowser;
- (void)didDismissPromptForBrowser:(BrowserWrapper*)inBrowser;
-(void)autosaveWindowFrame;
-(void)disableAutosave;
-(void)disableLoadPage;

View File

@ -368,6 +368,7 @@ enum BWCOpenDest {
- (void)performSearch:(SearchTextField *)inSearchField inView:(BWCOpenDest)inDest inBackground:(BOOL)inLoadInBG;
- (void)goToLocationFromToolbarURLField:(AutoCompleteTextField *)inURLField inView:(BWCOpenDest)inDest inBackground:(BOOL)inLoadInBG;
- (BrowserTabViewItem*)tabForBrowser:(BrowserWrapper*)inWrapper;
- (BookmarkViewController*)bookmarkViewControllerForCurrentTab;
- (void)bookmarkableTitle:(NSString **)outTitle URL:(NSString**)outURLString forWrapper:(BrowserWrapper*)inWrapper;
@ -1358,6 +1359,18 @@ enum BWCOpenDest {
#pragma mark -
- (BrowserTabViewItem*)tabForBrowser:(BrowserWrapper*)inWrapper
{
NSEnumerator* tabsEnum = [[mTabBrowser tabViewItems] objectEnumerator];
id curTabItem;
while ((curTabItem = [tabsEnum nextObject]))
{
if ([curTabItem isKindOfClass:[BrowserTabViewItem class]] && ([(BrowserTabViewItem*)curTabItem view] == inWrapper))
return curTabItem;
}
return nil;
}
- (BookmarkViewController*)bookmarkViewControllerForCurrentTab
{
id viewProvider = [mBrowserView contentViewProviderForURL:@"about:bookmarks"];
@ -2340,6 +2353,19 @@ enum BWCOpenDest {
}
}
- (void)willShowPromptForBrowser:(BrowserWrapper*)inBrowser
{
// bring the tab to the front (for security reasons)
BrowserTabViewItem* tabItem = [self tabForBrowser:inBrowser];
[mTabBrowser selectTabViewItem:tabItem];
// force a display, so that the tab view redraws before the sheet is shown
[mTabBrowser display];
}
- (void)didDismissPromptForBrowser:(BrowserWrapper*)inBrowser
{
}
- (void)createNewTab:(ENewTabContents)contents
{
BrowserTabViewItem* newTab = [self createNewTabItem];

View File

@ -732,6 +732,28 @@ static NSString* const kOfflineNotificationName = @"offlineModeChanged";
[[mWindow delegate] closeBrowserWindow:self];
}
//
// willShowPrompt
//
// Called before a prompt is shown for the contained view
//
- (void)willShowPrompt
{
[[mWindow delegate] willShowPromptForBrowser:self];
}
//
// didDismissPrompt
//
// Called after a prompt is shown for the contained view
//
- (void)didDismissPrompt
{
[[mWindow delegate] didDismissPromptForBrowser:self];
}
- (void)getTitle:(NSString **)outTitle andHref:(NSString**)outHrefString
{
*outTitle = *outHrefString = nil;

View File

@ -56,7 +56,6 @@ public:
NS_DECL_NSICOOKIEPROMPTSERVICE;
private:
NSWindow *GetNSWindowForDOMWindow(nsIDOMWindow* window);
NSString *GetCommonDialogLocaleString(const char *s);
NSString *GetButtonStringFromFlags(PRUint32 btnFlags, PRUint32 btnIDAndShift,
const PRUnichar *btnTitle);

View File

@ -38,13 +38,11 @@
#import "NSString+Utils.h"
#import "CHBrowserView.h"
#import "CHBrowserService.h"
#import "CocoaPromptService.h"
#include "nsCRT.h"
#include "nsIWindowWatcher.h"
#include "nsIWebBrowserChrome.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsString.h"
#include "nsServiceManagerUtils.h"
@ -71,11 +69,14 @@ CocoaPromptService::Alert(nsIDOMWindow *parent,
NSString* titleStr = [NSString stringWithPRUnichars:dialogTitle];
NSString* textStr = [NSString stringWithPRUnichars:text];
NSWindow* window = GetNSWindowForDOMWindow(parent);
if (!window)
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[controller alert:window title:titleStr text:textStr];
[browserView doBeforePromptDisplay];
[controller alert:[browserView getNativeWindow] title:titleStr text:textStr];
[browserView doAfterPromptDismissal];
return NS_OK;
}
@ -96,19 +97,24 @@ CocoaPromptService::AlertCheck(nsIDOMWindow *parent,
NSString* titleStr = [NSString stringWithPRUnichars:dialogTitle];
NSString* textStr = [NSString stringWithPRUnichars:text];
NSString* msgStr = [NSString stringWithPRUnichars:checkMsg];
NSWindow* window = GetNSWindowForDOMWindow(parent);
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
if (checkValue) {
BOOL valueBool = *checkValue ? YES : NO;
[controller alertCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
[controller alertCheck:[browserView getNativeWindow] title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
*checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
}
else {
[controller alert:window title:titleStr text:textStr];
[controller alert:[browserView getNativeWindow] title:titleStr text:textStr];
}
[browserView doAfterPromptDismissal];
return NS_OK;
}
@ -126,9 +132,14 @@ CocoaPromptService::Confirm(nsIDOMWindow *parent,
NSString* titleStr = [NSString stringWithPRUnichars:dialogTitle];
NSString* textStr = [NSString stringWithPRUnichars:text];
NSWindow* window = GetNSWindowForDOMWindow(parent);
*_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
*_retval = (PRBool)[controller confirm:[browserView getNativeWindow] title:titleStr text:textStr];
[browserView doAfterPromptDismissal];
return NS_OK;
}
@ -149,19 +160,24 @@ CocoaPromptService::ConfirmCheck(nsIDOMWindow *parent,
NSString* titleStr = [NSString stringWithPRUnichars:dialogTitle];
NSString* textStr = [NSString stringWithPRUnichars:text];
NSString* msgStr = [NSString stringWithPRUnichars:checkMsg];
NSWindow* window = GetNSWindowForDOMWindow(parent);
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
if (checkValue) {
BOOL valueBool = *checkValue ? YES : NO;
*_retval = (PRBool)[controller confirmCheck:window title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
*_retval = (PRBool)[controller confirmCheck:[browserView getNativeWindow] title:titleStr text:textStr checkMsg:msgStr checkValue:&valueBool];
*checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
}
else {
*_retval = (PRBool)[controller confirm:window title:titleStr text:textStr];
*_retval = (PRBool)[controller confirm:[browserView getNativeWindow] title:titleStr text:textStr];
}
[browserView doAfterPromptDismissal];
return NS_OK;
}
@ -192,26 +208,33 @@ CocoaPromptService::ConfirmEx(nsIDOMWindow *parent,
NSString* titleStr = [NSString stringWithPRUnichars:dialogTitle];
NSString* textStr = [NSString stringWithPRUnichars:text];
NSString* msgStr = [NSString stringWithPRUnichars:checkMsg];
NSWindow* window = GetNSWindowForDOMWindow(parent);
NSString* btn1Str = GetButtonStringFromFlags(buttonFlags, kButton0, button0Title);
NSString* btn2Str = GetButtonStringFromFlags(buttonFlags, kButton1, button1Title);
NSString* btn3Str = GetButtonStringFromFlags(buttonFlags, kButton2, button2Title);
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
if (checkValue) {
BOOL valueBool = *checkValue ? YES : NO;
*buttonPressed = [controller confirmCheckEx:window title:titleStr text:textStr
*buttonPressed = [controller confirmCheckEx:[browserView getNativeWindow] title:titleStr text:textStr
button1: btn1Str button2: btn2Str button3: btn3Str
checkMsg:msgStr checkValue:&valueBool];
*checkValue = (valueBool == YES) ? PR_TRUE : PR_FALSE;
}
else {
*buttonPressed = [controller confirmEx:window title:titleStr text:textStr
*buttonPressed = [controller confirmEx:[browserView getNativeWindow] title:titleStr text:textStr
button1: btn1Str button2: btn2Str button3: btn3Str];
}
[browserView doAfterPromptDismissal];
return NS_OK;
}
@ -242,9 +265,14 @@ CocoaPromptService::Prompt(nsIDOMWindow *parent,
if (checkValue) {
valueBool = *checkValue ? YES : NO;
}
NSWindow* window = GetNSWindowForDOMWindow(parent);
*_retval = (PRBool)[controller prompt:window title:titleStr text:textStr promptText:valueStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
*_retval = (PRBool)[controller prompt:[browserView getNativeWindow] title:titleStr text:textStr promptText:valueStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
[browserView doAfterPromptDismissal];
// the caller only cares about |value| and |checkValue| if |_retval|
// is something other than cancel. If it is, we'd leak any string we allocated
@ -288,9 +316,14 @@ CocoaPromptService::PromptUsernameAndPassword(nsIDOMWindow *parent,
if (checkValue) {
valueBool = *checkValue ? YES : NO;
}
NSWindow* window = GetNSWindowForDOMWindow(parent);
*_retval = (PRBool)[controller promptUserNameAndPassword:window title:titleStr text:textStr userNameText:userNameStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
*_retval = (PRBool)[controller promptUserNameAndPassword:[browserView getNativeWindow] title:titleStr text:textStr userNameText:userNameStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
[browserView doAfterPromptDismissal];
// the caller only cares about |username|, |password|, and |checkValue| if |_retval|
// is something other than cancel. If it is, we'd leak any string we allocated
@ -333,9 +366,14 @@ CocoaPromptService::PromptPassword(nsIDOMWindow *parent,
if (checkValue) {
valueBool = *checkValue ? YES : NO;
}
NSWindow* window = GetNSWindowForDOMWindow(parent);
*_retval = (PRBool)[controller promptPassword:window title:titleStr text:textStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:parent];
if (!browserView)
return NS_ERROR_FAILURE;
[browserView doBeforePromptDisplay];
*_retval = (PRBool)[controller promptPassword:[browserView getNativeWindow] title:titleStr text:textStr passwordText:passwordStr checkMsg:msgStr checkValue:&valueBool doCheck:(checkValue != nsnull)];
[browserView doAfterPromptDismissal];
// the caller only cares about |password| and |checkValue| if |_retval|
// is something other than cancel. If it is, we'd leak any string we allocated
@ -368,34 +406,6 @@ CocoaPromptService::Select(nsIDOMWindow *parent,
return NS_ERROR_NOT_IMPLEMENTED;
}
NSWindow*
CocoaPromptService::GetNSWindowForDOMWindow(nsIDOMWindow* window)
{
nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
if (!watcher) {
return nsnull;
}
nsCOMPtr<nsIWebBrowserChrome> chrome;
watcher->GetChromeForWindow(window, getter_AddRefs(chrome));
if (!chrome) {
return nsnull;
}
nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_QueryInterface(chrome));
if (!siteWindow) {
return nsnull;
}
NSWindow* nswin;
nsresult rv = siteWindow->GetSiteWindow((void**)&nswin);
if (NS_FAILED(rv))
return nsnull;
return nswin;
}
NSString *
CocoaPromptService::GetCommonDialogLocaleString(const char *key)
{

View File

@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */
#import "NSString+Utils.h"
#import "KeychainService.h"
#import "CHBrowserService.h"
#import "PreferenceManager.h"
@ -858,29 +859,8 @@ KeychainFormSubmitObserver::Notify(nsIContent* node, nsIDOMWindowInternal* windo
NSWindow*
KeychainFormSubmitObserver::GetNSWindow(nsIDOMWindowInternal* inWindow)
{
//
// TODO: Refactor: Getting the NSWindow for the nsIDOMWindowInternal
// is already implemented in CocoaPromptService.
//
nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
if (!watcher)
return nsnull;
nsCOMPtr<nsIWebBrowserChrome> chrome;
watcher->GetChromeForWindow(inWindow, getter_AddRefs(chrome));
if (!chrome)
return nsnull;
nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_QueryInterface(chrome));
if (!siteWindow)
return nsnull;
NSWindow* nswindow;
nsresult rv = siteWindow->GetSiteWindow((void**)&nswindow);
if (NS_FAILED(rv))
return nsnull;
return nswindow;
CHBrowserView* browserView = [CHBrowserView browserViewFromDOMWindow:inWindow];
return [browserView getNativeWindow];
}
KeychainPromptResult

View File

@ -514,6 +514,8 @@ CHBrowserListener::SetTitle(const PRUnichar * aTitle)
}
/* [noscript] readonly attribute voidPtr siteWindow; */
// We return the CHBrowserView here, which isn't a window, but allows callers
// to tell which tab something is coming from.
NS_IMETHODIMP
CHBrowserListener::GetSiteWindow(void * *aSiteWindow)
{
@ -523,12 +525,10 @@ CHBrowserListener::GetSiteWindow(void * *aSiteWindow)
return NS_ERROR_FAILURE;
}
NSWindow* window = [mView getNativeWindow];
if (!window) {
if (!mView)
return NS_ERROR_FAILURE;
}
*aSiteWindow = (void*)window;
*aSiteWindow = (void*)mView;
return NS_OK;
}

View File

@ -118,6 +118,10 @@ typedef enum {
// behavior.
- (void)closeBrowserWindow;
// Called before and after a prompt is shown for the contained view
- (void)willShowPrompt;
- (void)didDismissPrompt;
@end
enum {
@ -147,6 +151,9 @@ enum {
BOOL mUseGlobalPrintSettings;
}
// class method to get at the browser view for a given nsIDOMWindow
+ (CHBrowserView*)browserViewFromDOMWindow:(nsIDOMWindow*)inWindow;
// NSView overrides
- (id)initWithFrame:(NSRect)frame;
- (id)initWithFrame:(NSRect)frame andWindow:(NSWindow*)aWindow;
@ -211,6 +218,12 @@ enum {
- (BOOL)canMakeTextBigger;
- (BOOL)canMakeTextSmaller;
// ideally these would not have to be called from outside the CHBrowerView, but currently
// the cocoa impl of nsIPromptService is at the app level, so it needs to call down
// here. We'll just turn around and call the CHBrowserContainer methods
- (void)doBeforePromptDisplay;
- (void)doAfterPromptDismissal;
-(NSString*)getCurrentURLSpec;
- (void)setActive: (BOOL)aIsActive;

View File

@ -36,6 +36,8 @@
* ***** END LICENSE BLOCK ***** */
#import "NSString+Utils.h"
#import "NSPasteboard+Utils.h"
#import "CHClickListener.h"
#include "nsCWebBrowser.h"
@ -66,14 +68,16 @@
#include "nsIMarkupDocumentViewer.h"
#include "nsIContentViewer.h"
// nsIDOMWindow->CHBrowserView
#include "nsIWindowWatcher.h"
#include "nsIEmbeddingSiteWindow.h"
// Saving of links/images/docs
#include "nsIWebBrowserFocus.h"
#include "nsIDOMNSDocument.h"
#include "nsIDOMLocation.h"
#include "nsIWebBrowserPersist.h"
#include "nsIProperties.h"
//#include "nsIRequest.h"
//#include "nsIPrefService.h"
#include "nsISHistory.h"
#include "nsIHistoryEntry.h"
#include "nsISHEntry.h"
@ -95,7 +99,6 @@ typedef unsigned int DragReference;
// Cut/copy/paste
#include "nsIClipboardCommands.h"
#include "nsIInterfaceRequestorUtils.h"
#import "NSPasteboard+Utils.h"
// Undo/redo
#include "nsICommandManager.h"
@ -110,14 +113,42 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
@interface CHBrowserView(Private)
- (id<CHBrowserContainer>)getBrowserContainer;
- (nsIContentViewer*)getContentViewer; // addrefs return value
- (float)getTextZoom;
- (void)incrementTextZoom:(float)increment min:(float)min max:(float)max;
- (nsIDocShell*)getDocShell;
@end
#pragma mark -
@implementation CHBrowserView
+ (CHBrowserView*)browserViewFromDOMWindow:(nsIDOMWindow*)inWindow
{
nsCOMPtr<nsIWindowWatcher> watcher(do_GetService("@mozilla.org/embedcomp/window-watcher;1"));
if (!watcher)
return nil;
nsCOMPtr<nsIWebBrowserChrome> chrome;
watcher->GetChromeForWindow(inWindow, getter_AddRefs(chrome));
if (!chrome)
return nil;
nsCOMPtr<nsIEmbeddingSiteWindow> siteWindow(do_QueryInterface(chrome));
if (!siteWindow)
return nil;
CHBrowserView* browserView;
nsresult rv = siteWindow->GetSiteWindow((void**)&browserView);
if (NS_FAILED(rv))
return nil;
return browserView;
}
- (id)initWithFrame:(NSRect)frame andWindow:(NSWindow*)aWindow
{
mWindow = aWindow;
@ -881,6 +912,16 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
[self doCommand: "cmd_selectBottom"];
}
- (void)doBeforePromptDisplay
{
[[self getBrowserContainer] willShowPrompt];
}
- (void)doAfterPromptDismissal
{
[[self getBrowserContainer] didDismissPrompt];
}
// how does this differ from getCurrentURI?
-(NSString*)getCurrentURLSpec
{
@ -924,13 +965,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
-(NSMenu*)getContextMenu
{
if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
{
id<CHBrowserContainer> browserContainer = [self superview];
return [browserContainer getContextMenu];
}
return nil;
return [[self getBrowserContainer] getContextMenu];
}
-(NSWindow*)getNativeWindow
@ -946,13 +981,7 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
// Finally, see if our parent responds to the getNativeWindow selector,
// and if they do, let them handle it.
if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
{
id<CHBrowserContainer> browserContainer = [self superview];
return [browserContainer getNativeWindow];
}
return nil;
return [[self getBrowserContainer] getNativeWindow];
}
@ -988,6 +1017,15 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
return global->GetDocShell();
}
- (id<CHBrowserContainer>)getBrowserContainer
{
// i'm not sure why this doesn't return whatever -setContainer: was called with
if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
return (id<CHBrowserContainer>)[self superview];
return nil;
}
- (nsIContentViewer*)getContentViewer // addrefs return value
{
nsIDocShell* docShell = [self getDocShell];
@ -1033,11 +1071,10 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
- (BOOL)shouldAcceptDrag:(id <NSDraggingInfo>)sender
{
if ([[self superview] conformsToProtocol:@protocol(CHBrowserContainer)])
{
id<CHBrowserContainer> browserContainer = [self superview];
id<CHBrowserContainer> browserContainer = [self getBrowserContainer];
if (browserContainer)
return [browserContainer shouldAcceptDragFromSource:[sender draggingSource]];
}
return YES;
}