Fixing bug 262887. Make dialogs opened through the DOM make the opening tab the current tab. r=ben@mozilla.org, dveditz@cruzio.com, sr=bryner@brianryner.com

This commit is contained in:
jst%mozilla.jstenback.com 2004-11-03 17:06:21 +00:00
Родитель 13597fb587
Коммит 3daabe5d96
5 изменённых файлов: 151 добавлений и 62 удалений

Просмотреть файл

@ -2724,8 +2724,18 @@ nsBrowserStatusHandler.prototype =
location = locationURI.spec;
} catch (exception) {}
setTimeout(function(loc, aloc) { gURLBar.value = loc; SetPageProxyState("valid", aloc);}, 0, location, aLocation);
if (getBrowser().forceSyncURLBarUpdate) {
gURLBar.value = ""; // hack for bug 249322
gURLBar.value = location;
SetPageProxyState("valid", aLocation);
} else {
setTimeout(function(loc, aloc) {
gURLBar.value = ""; // hack for bug 249322
gURLBar.value = loc;
SetPageProxyState("valid", aloc);
}, 0, location, aLocation);
}
// Setting the urlBar value in some cases causes userTypedValue to
// become set because of oninput, so reset it to its old value.
browser.userTypedValue = userTypedValue;

Просмотреть файл

@ -2067,6 +2067,33 @@ GlobalWindowImpl::GetLength(PRUint32* aLength)
return NS_ERROR_FAILURE;
}
PRBool
GlobalWindowImpl::DispatchCustomEvent(const char *aEventName)
{
nsCOMPtr<nsIDOMDocumentEvent> doc(do_QueryInterface(mDocument));
nsCOMPtr<nsIDOMEvent> event;
// Doesn't this seem backwards? Seems like
// nsEventStateManager::DispatchNewEvent() screws up on the
// logic for its prevent default argument...
PRBool preventDefault = PR_TRUE;
if (doc) {
doc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
if (privateEvent) {
event->InitEvent(NS_ConvertASCIItoUTF16(aEventName), PR_TRUE, PR_TRUE);
privateEvent->SetTrusted(PR_TRUE);
DispatchEvent(event, &preventDefault);
}
}
return preventDefault;
}
NS_IMETHODIMP GlobalWindowImpl::SetFullScreen(PRBool aFullScreen)
{
// Only chrome can change our fullScreen mode.
@ -2093,25 +2120,13 @@ NS_IMETHODIMP GlobalWindowImpl::SetFullScreen(PRBool aFullScreen)
if (itemType != nsIDocShellTreeItem::typeChrome)
return NS_ERROR_FAILURE;
// dispatch an onfullscreen DOM event so that XUL apps can
// dispatch a "fullscreen" DOM event so that XUL apps can
// respond visually if we are kicked into full screen mode
nsCOMPtr<nsIDOMDocumentEvent> doc(do_QueryInterface(mDocument));
nsCOMPtr<nsIDOMEvent> event;
doc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
if (!event)
return NS_ERROR_FAILURE;
if (!DispatchCustomEvent("fullscreen")) {
// event handlers can prevent us from going into full-screen mode
event->InitEvent(NS_LITERAL_STRING("fullscreen"), PR_FALSE, PR_TRUE);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
privateEvent->SetTrusted(PR_TRUE);
PRBool allowDefault;
DispatchEvent(event, &allowDefault);
// event handlers can prevent us from going into full-screen mode
if (!allowDefault)
return NS_OK;
}
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin;
GetTreeOwner(getter_AddRefs(treeOwnerAsWin));
@ -2278,7 +2293,20 @@ GlobalWindowImpl::MakeScriptDialogTitle(const nsAString &aInTitle,
NS_IMETHODIMP
GlobalWindowImpl::Alert(const nsAString& aString)
{
NS_ENSURE_STATE(mDocShell);
nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
// Reset popup state while opening a modal dialog, and firing events
// about the dialog, to prevent the current state from being active
// the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
if (!DispatchCustomEvent("DOMWillOpenModalDialog")) {
// Someone chose to prevent the default action for this event,
// if so, don't show the dialog after all...
return NS_OK;
}
// Special handling for alert(null) in JS for backwards
// compatibility.
@ -2287,9 +2315,6 @@ GlobalWindowImpl::Alert(const nsAString& aString)
const nsAString *str = DOMStringIsNull(aString) ? &null_str : &aString;
nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
// Test whether title needs to prefixed with [script]
nsAutoString newTitle;
const PRUnichar *title = nsnull;
@ -2306,17 +2331,30 @@ GlobalWindowImpl::Alert(const nsAString& aString)
// pending reflows.
EnsureReflowFlushAndPaint();
// Reset popup state while opening a window to prevent the current
// state from being active the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
nsresult rv = prompter->Alert(title, PromiseFlatString(*str).get());
return prompter->Alert(title, PromiseFlatString(*str).get());
DispatchCustomEvent("DOMModalDialogClosed");
return rv;
}
NS_IMETHODIMP
GlobalWindowImpl::Confirm(const nsAString& aString, PRBool* aReturn)
{
NS_ENSURE_STATE(mDocShell);
nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
// Reset popup state while opening a modal dialog, and firing events
// about the dialog, to prevent the current state from being active
// the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
if (!DispatchCustomEvent("DOMWillOpenModalDialog")) {
// Someone chose to prevent the default action for this event,
// if so, don't show the dialog after all...
return NS_OK;
}
*aReturn = PR_FALSE;
@ -2332,18 +2370,16 @@ GlobalWindowImpl::Confirm(const nsAString& aString, PRBool* aReturn)
"service");
}
nsCOMPtr<nsIPrompt> prompter(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
// Before bringing up the window, unsuppress painting and flush
// pending reflows.
EnsureReflowFlushAndPaint();
// Reset popup state while opening a window to prevent the current
// state from being active the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
nsresult rv = prompter->Confirm(title, PromiseFlatString(aString).get(),
aReturn);
return prompter->Confirm(title, PromiseFlatString(aString).get(), aReturn);
DispatchCustomEvent("DOMModalDialogClosed");
return rv;
}
NS_IMETHODIMP
@ -2355,11 +2391,21 @@ GlobalWindowImpl::Prompt(const nsAString& aMessage,
{
SetDOMStringToNull(aReturn);
NS_ENSURE_STATE(mDocShell);
nsCOMPtr<nsIAuthPrompt> prompter(do_GetInterface(mDocShell));
NS_ENSURE_TRUE(prompter, NS_ERROR_FAILURE);
// Reset popup state while opening a modal dialog, and firing events
// about the dialog, to prevent the current state from being active
// the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
if (!DispatchCustomEvent("DOMWillOpenModalDialog")) {
// Someone chose to prevent the default action for this event,
// if so, don't show the dialog after all...
return NS_OK;
}
PRBool b;
nsXPIDLString uniResult;
@ -2377,15 +2423,14 @@ GlobalWindowImpl::Prompt(const nsAString& aMessage,
title.Assign(aTitle);
}
// Reset popup state while opening a window to prevent the current
// state from being active the whole time a modal dialog is open.
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
nsresult rv = prompter->Prompt(title.get(),
PromiseFlatString(aMessage).get(), nsnull,
aSavePassword,
PromiseFlatString(aInitial).get(),
getter_Copies(uniResult), &b);
DispatchCustomEvent("DOMModalDialogClosed");
NS_ENSURE_SUCCESS(rv, rv);
if (uniResult && b) {
@ -3440,28 +3485,11 @@ GlobalWindowImpl::Close()
// could be abused by content code, but do we care? I don't think
// so...
nsCOMPtr<nsIDOMDocumentEvent> doc(do_QueryInterface(mDocument));
nsCOMPtr<nsIDOMEvent> event;
if (!DispatchCustomEvent("DOMWindowClose")) {
// Someone chose to prevent the default action for this event, if
// so, let's not close this window after all...
if (doc) {
doc->CreateEvent(NS_LITERAL_STRING("Events"), getter_AddRefs(event));
}
if (event) {
event->InitEvent(NS_LITERAL_STRING("DOMWindowClose"), PR_TRUE, PR_TRUE);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
privateEvent->SetTrusted(PR_TRUE);
PRBool executeDefault = PR_TRUE;
DispatchEvent(event, &executeDefault);
if (!executeDefault) {
// Someone chose to prevent the default action for this event,
// if so, let's not close this window after all...
return NS_OK;
}
return NS_OK;
}
// Flag that we were closed.

Просмотреть файл

@ -288,7 +288,8 @@ protected:
return GetParentInternal() != nsnull;
}
protected:
PRBool DispatchCustomEvent(const char *aEventName);
// When adding new member variables, be careful not to create cycles
// through JavaScript. If there is any chance that a member variable
// could own objects that are implemented in JavaScript, then those

Просмотреть файл

@ -151,6 +151,9 @@
<field name="mContextTab">
null
</field>
<field name="mModalDialogShowing">
false
</field>
<!-- A web progress listener object definition for a given tab. -->
<method name="mTabProgressListener">
@ -1376,6 +1379,9 @@
onget="return this.mCurrentBrowser.userTypedValue;"
onset="return this.mCurrentBrowser.userTypedValue = val;"/>
<property name="forceSyncURLBarUpdate"
onget="return this.mModalDialogShowing;"/>
<constructor>
<![CDATA[
this.mCurrentBrowser = this.mPanelContainer.firstChild;
@ -1423,6 +1429,32 @@
event.preventDefault();
]]>
</handler>
<handler event="DOMWillOpenModalDialog">
<![CDATA[
if (!event.isTrusted)
return;
// We're about to open a modal dialog, make sure the opening
// tab is brought to the front.
for (var i = 0; i < browsers.length; ++i) {
if (this.getBrowserAtIndex(i).contentWindow == event.target) {
this.mModalDialogShowing = true;
this.selectedTab = this.mTabContainer.childNodes[i];
break;
}
}
]]>
</handler>
<handler event="DOMModalDialogClosed">
<![CDATA[
if (!event.isTrusted)
return;
this.mModalDialogShowing = false;
]]>
</handler>
</handlers>
</binding>

Просмотреть файл

@ -1566,6 +1566,24 @@
event.preventDefault();
]]>
</handler>
<handler event="DOMWillOpenModalDialog">
<![CDATA[
if (!event.isTrusted)
return;
// We're about to open a modal dialog, make sure the opening
// tab is brought to the front.
const browsers = this.browsers;
for (var i = 0; i < browsers.length; ++i) {
if (browsers[i].contentWindow == event.target) {
this.selectedTab = this.mTabContainer.childNodes[i];
break;
}
}
]]>
</handler>
</handlers>
</binding>