mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-14 00:14:33 +00:00
Bug 1045987 - Fix doorhanger notifications for the login manager. r=billm/dolske
This commit is contained in:
parent
985af86677
commit
5323fc52d6
@ -372,6 +372,16 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="getBrowserForContentWindow">
|
||||
<parameter name="aWindow"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var tab = this._getTabForContentWindow(aWindow);
|
||||
return tab ? tab.linkedBrowser : null;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_getTabForContentWindow">
|
||||
<parameter name="aWindow"/>
|
||||
<body>
|
||||
@ -388,7 +398,9 @@
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.browsers.length; i++) {
|
||||
if (this.browsers[i].contentWindow == aWindow)
|
||||
// NB: We use contentWindowAsCPOW so that this code works both
|
||||
// for remote browsers as well. aWindow may be a CPOW.
|
||||
if (this.browsers[i].contentWindowAsCPOW == aWindow)
|
||||
return this.tabs[i];
|
||||
}
|
||||
return null;
|
||||
|
@ -123,6 +123,12 @@ LoginManagerPrompter.prototype = {
|
||||
},
|
||||
|
||||
|
||||
setE10sData : function (aBrowser) {
|
||||
// XXX Implement me!
|
||||
throw new Error("Not Yet Implemented");
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* promptToSavePassword
|
||||
*
|
||||
|
@ -108,6 +108,9 @@ LoginManagerPrompter.prototype = {
|
||||
this.log("===== initialized =====");
|
||||
},
|
||||
|
||||
setE10sData : function (aBrowser) {
|
||||
throw new Error("This should be filled in when Android is multiprocess");
|
||||
},
|
||||
|
||||
/*
|
||||
* promptToSavePassword
|
||||
|
@ -541,13 +541,17 @@ var LoginManagerContent = {
|
||||
value: oldPasswordField.value } :
|
||||
null;
|
||||
|
||||
// Make sure to pass the opener's top in case it was in a frame.
|
||||
let opener = win.opener ? win.opener.top : null;
|
||||
|
||||
let messageManager = messageManagerFromWindow(win);
|
||||
messageManager.sendAsyncMessage("RemoteLogins:onFormSubmit",
|
||||
{ hostname: hostname,
|
||||
formSubmitURL: formSubmitURL,
|
||||
usernameField: mockUsername,
|
||||
newPasswordField: mockPassword,
|
||||
oldPasswordField: mockOldPassword });
|
||||
oldPasswordField: mockOldPassword },
|
||||
{ openerWin: opener });
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -69,7 +69,6 @@ var LoginManagerParent = {
|
||||
|
||||
receiveMessage: function (msg) {
|
||||
let data = msg.data;
|
||||
|
||||
switch (msg.name) {
|
||||
case "RemoteLogins:findLogins": {
|
||||
// TODO Verify msg.target's principals against the formOrigin?
|
||||
@ -88,6 +87,7 @@ var LoginManagerParent = {
|
||||
data.usernameField,
|
||||
data.newPasswordField,
|
||||
data.oldPasswordField,
|
||||
msg.objects.openerWin,
|
||||
msg.target);
|
||||
break;
|
||||
}
|
||||
@ -203,7 +203,7 @@ var LoginManagerParent = {
|
||||
|
||||
onFormSubmit: function(hostname, formSubmitURL,
|
||||
usernameField, newPasswordField,
|
||||
oldPasswordField,
|
||||
oldPasswordField, opener,
|
||||
target) {
|
||||
function getPrompter() {
|
||||
var prompterSvc = Cc["@mozilla.org/login-manager/prompter;1"].
|
||||
@ -216,6 +216,8 @@ var LoginManagerParent = {
|
||||
prompterSvc.init(target.isRemoteBrowser ?
|
||||
target.ownerDocument.defaultView :
|
||||
target.contentWindow);
|
||||
if (target.isRemoteBrowser)
|
||||
prompterSvc.setE10sData({ browser: target, opener: opener });
|
||||
return prompterSvc;
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,7 @@
|
||||
interface nsILoginInfo;
|
||||
interface nsIDOMWindow;
|
||||
|
||||
[scriptable, uuid(68b3cb59-51b8-4c57-bd7f-b2ce955a593d)]
|
||||
|
||||
[scriptable, uuid(88b75787-a78c-43aa-bfe8-52c3248b8dfd)]
|
||||
interface nsILoginManagerPrompter : nsISupports {
|
||||
/**
|
||||
* Initialize the prompter. Must be called before using other interfaces.
|
||||
@ -22,6 +21,15 @@ interface nsILoginManagerPrompter : nsISupports {
|
||||
*/
|
||||
void init(in nsIDOMWindow aWindow);
|
||||
|
||||
/**
|
||||
* If the caller knows which browser this prompter is being created for,
|
||||
* they can call this function to avoid having to calculate it from the
|
||||
* window passed to init.
|
||||
*
|
||||
* @param aBrowser the <browser> to use for this prompter.
|
||||
*/
|
||||
void setE10sData(in jsval aData);
|
||||
|
||||
/**
|
||||
* Ask the user if they want to save a login (Yes, Never, Not Now)
|
||||
*
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* vim: set ts=4 sts=4 sw=4 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
@ -199,6 +200,8 @@ LoginManagerPrompter.prototype = {
|
||||
|
||||
_factory : null,
|
||||
_window : null,
|
||||
_browser : null,
|
||||
_opener : null,
|
||||
_debug : false, // mirrors signon.debug
|
||||
|
||||
__pwmgr : null, // Password Manager service
|
||||
@ -702,12 +705,21 @@ LoginManagerPrompter.prototype = {
|
||||
init : function (aWindow, aFactory) {
|
||||
this._window = aWindow;
|
||||
this._factory = aFactory || null;
|
||||
this._browser = null;
|
||||
this._opener = null;
|
||||
|
||||
var prefBranch = Services.prefs.getBranch("signon.");
|
||||
this._debug = prefBranch.getBoolPref("debug");
|
||||
this.log("===== initialized =====");
|
||||
},
|
||||
|
||||
setE10sData : function (aData) {
|
||||
if (!(this._window instanceof Ci.nsIDOMChromeWindow))
|
||||
throw new Error("Unexpected call");
|
||||
this._browser = aData.browser;
|
||||
this._opener = aData.opener;
|
||||
},
|
||||
|
||||
|
||||
/*
|
||||
* promptToSavePassword
|
||||
@ -823,10 +835,7 @@ LoginManagerPrompter.prototype = {
|
||||
}
|
||||
];
|
||||
|
||||
var notifyWin = this._getNotifyWindow();
|
||||
var chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
|
||||
var browser = chromeWin.gBrowser.
|
||||
getBrowserForDocument(notifyWin.top.document);
|
||||
var { browser } = this._getNotifyWindow();
|
||||
|
||||
aNotifyObj.show(browser, "password-save", notificationText,
|
||||
"password-notification-icon", mainAction,
|
||||
@ -1021,10 +1030,7 @@ LoginManagerPrompter.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
var notifyWin = this._getNotifyWindow();
|
||||
var chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
|
||||
var browser = chromeWin.gBrowser.
|
||||
getBrowserForDocument(notifyWin.top.document);
|
||||
var { browser } = this._getNotifyWindow();
|
||||
|
||||
aNotifyObj.show(browser, "password-change", notificationText,
|
||||
"password-notification-icon", mainAction,
|
||||
@ -1165,6 +1171,9 @@ LoginManagerPrompter.prototype = {
|
||||
* Given a content DOM window, returns the chrome window it's in.
|
||||
*/
|
||||
_getChromeWindow: function (aWindow) {
|
||||
// In e10s, aWindow may already be a chrome window.
|
||||
if (aWindow instanceof Ci.nsIDOMChromeWindow)
|
||||
return aWindow;
|
||||
var chromeWin = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
@ -1181,33 +1190,61 @@ LoginManagerPrompter.prototype = {
|
||||
try {
|
||||
// Get topmost window, in case we're in a frame.
|
||||
var notifyWin = this._window.top;
|
||||
var isE10s = (notifyWin instanceof Ci.nsIDOMChromeWindow);
|
||||
var useOpener = false;
|
||||
|
||||
// Some sites pop up a temporary login window, when disappears
|
||||
// Some sites pop up a temporary login window, which disappears
|
||||
// upon submission of credentials. We want to put the notification
|
||||
// bar in the opener window if this seems to be happening.
|
||||
if (notifyWin.opener) {
|
||||
var chromeDoc = this._getChromeWindow(notifyWin).
|
||||
document.documentElement;
|
||||
var webnav = notifyWin.
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIWebNavigation);
|
||||
|
||||
var hasHistory;
|
||||
if (isE10s) {
|
||||
if (!this._browser)
|
||||
throw new Error("Expected a browser in e10s");
|
||||
hasHistory = this._browser.canGoBack;
|
||||
} else {
|
||||
var webnav = notifyWin.
|
||||
QueryInterface(Ci.nsIInterfaceRequestor).
|
||||
getInterface(Ci.nsIWebNavigation);
|
||||
hasHistory = webnav.sessionHistory.count > 1;
|
||||
}
|
||||
|
||||
// Check to see if the current window was opened with chrome
|
||||
// disabled, and if so use the opener window. But if the window
|
||||
// has been used to visit other pages (ie, has a history),
|
||||
// assume it'll stick around and *don't* use the opener.
|
||||
if (chromeDoc.getAttribute("chromehidden") &&
|
||||
webnav.sessionHistory.count == 1) {
|
||||
if (chromeDoc.getAttribute("chromehidden") && !hasHistory) {
|
||||
this.log("Using opener window for notification bar.");
|
||||
notifyWin = notifyWin.opener;
|
||||
useOpener = true;
|
||||
}
|
||||
}
|
||||
|
||||
return notifyWin;
|
||||
let browser;
|
||||
if (useOpener && isE10s) {
|
||||
// In e10s, we have to reconstruct the opener browser from
|
||||
// the CPOW passed in the message (and then passed to us in
|
||||
// setE10sData).
|
||||
// NB: notifyWin is now the chrome window for the opening
|
||||
// window.
|
||||
|
||||
browser = notifyWin.gBrowser.getBrowserForContentWindow(this._opener);
|
||||
} else if (isE10s) {
|
||||
browser = this._browser;
|
||||
} else {
|
||||
var chromeWin = this._getChromeWindow(notifyWin).wrappedJSObject;
|
||||
browser = chromeWin.gBrowser
|
||||
.getBrowserForDocument(notifyWin.top.document);
|
||||
}
|
||||
|
||||
return { notifyWin: notifyWin, browser: browser };
|
||||
|
||||
} catch (e) {
|
||||
// If any errors happen, just assume no notification box.
|
||||
this.log("Unable to get notify window");
|
||||
this.log("Unable to get notify window: " + e.fileName + ":" + e.lineNumber + ": " + e.message);
|
||||
return null;
|
||||
}
|
||||
},
|
||||
@ -1223,7 +1260,7 @@ LoginManagerPrompter.prototype = {
|
||||
let popupNote = null;
|
||||
|
||||
try {
|
||||
let notifyWin = this._getNotifyWindow();
|
||||
let { notifyWin } = this._getNotifyWindow();
|
||||
|
||||
// Get the chrome window for the content window we're using.
|
||||
// .wrappedJSObject needed here -- see bug 422974 comment 5.
|
||||
@ -1248,7 +1285,7 @@ LoginManagerPrompter.prototype = {
|
||||
let notifyBox = null;
|
||||
|
||||
try {
|
||||
let notifyWin = this._getNotifyWindow();
|
||||
let { notifyWin } = this._getNotifyWindow();
|
||||
|
||||
// Get the chrome window for the content window we're using.
|
||||
// .wrappedJSObject needed here -- see bug 422974 comment 5.
|
||||
|
Loading…
x
Reference in New Issue
Block a user