Bug 1077168 - Make WebappManager.jsm use the top window id to select which browser to show notifications in. r=felipe.

--HG--
extra : rebase_source : c54b8d8fc9fc01af47fb96d692226532ea3f4c69
This commit is contained in:
Mike Conley 2015-01-27 18:32:40 -05:00
parent a80a4c4077
commit 6fc217517d
5 changed files with 85 additions and 28 deletions

View File

@ -116,6 +116,9 @@
<field name="mIsBusy">
false
</field>
<field name="_outerWindowIDBrowserMap">
new Map();
</field>
<field name="arrowKeysShouldWrap" readonly="true">
#ifdef XP_MACOSX
true
@ -381,6 +384,15 @@
</body>
</method>
<method name="getBrowserForOuterWindowID">
<parameter name="aID"/>
<body>
<![CDATA[
return this._outerWindowIDBrowserMap.get(aID);
]]>
</body>
</method>
<method name="_getTabForContentWindow">
<parameter name="aWindow"/>
<body>
@ -1758,6 +1770,13 @@
b = this._createBrowser({remote, uriIsAboutBlank});
}
// A remote browser doesn't initially have the outerWindowID
// set. Once a remote browser initializes, it sends the Browser:Init
// message, and we map the browser at that point.
if (!remote) {
this._outerWindowIDBrowserMap.set(b.outerWindowID, b);
}
let notificationbox = this.getNotificationBox(b);
var position = this.tabs.length - 1;
var uniqueId = this._generateUniquePanelID();
@ -2225,6 +2244,7 @@
this.mTabListeners.splice(aTab._tPos, 1);
var browser = this.getBrowserForTab(aTab);
this._outerWindowIDBrowserMap.delete(browser.outerWindowID);
// Because of the way XBL works (fields just set JS
// properties on the element) and the code we have in place
@ -3225,6 +3245,8 @@
let tab = this.getTabForBrowser(browser);
if (!tab)
return;
this._outerWindowIDBrowserMap.set(browser.outerWindowID, browser);
browser.messageManager.sendAsyncMessage("Browser:AppTab", { isAppTab: tab.pinned })
break;
}
@ -3291,6 +3313,9 @@
// If this window has remote tabs, switch to our tabpanels fork
// which does asynchronous tab switching.
this.mPanelContainer.classList.add("tabbrowser-tabpanels");
} else {
this._outerWindowIDBrowserMap.set(this.mCurrentBrowser.outerWindowID,
this.mCurrentBrowser);
}
messageManager.addMessageListener("DOMWebNotificationClicked", this);
]]>

View File

@ -35,6 +35,10 @@ this.WebappManager = {
Services.obs.addObserver(this, "webapps-ask-uninstall", false);
Services.obs.addObserver(this, "webapps-launch", false);
Services.obs.addObserver(this, "webapps-uninstall", false);
cpmm.sendAsyncMessage("Webapps:RegisterForMessages",
{ messages: ["Webapps:Install:Return:OK",
"Webapps:Install:Return:KO",
"Webapps:UpdateState"]});
cpmm.addMessageListener("Webapps:Install:Return:OK", this);
cpmm.addMessageListener("Webapps:Install:Return:KO", this);
cpmm.addMessageListener("Webapps:UpdateState", this);
@ -45,6 +49,10 @@ this.WebappManager = {
Services.obs.removeObserver(this, "webapps-ask-uninstall");
Services.obs.removeObserver(this, "webapps-launch");
Services.obs.removeObserver(this, "webapps-uninstall");
cpmm.sendAsyncMessage("Webapps:UnregisterForMessages",
["Webapps:Install:Return:OK",
"Webapps:Install:Return:KO",
"Webapps:UpdateState"]);
cpmm.removeMessageListener("Webapps:Install:Return:OK", this);
cpmm.removeMessageListener("Webapps:Install:Return:KO", this);
cpmm.removeMessageListener("Webapps:UpdateState", this);
@ -84,18 +92,18 @@ this.WebappManager = {
let data = JSON.parse(aData);
data.mm = aSubject;
let win;
let browser;
switch(aTopic) {
case "webapps-ask-install":
win = this._getWindowForId(data.oid);
if (win && win.location.href == data.from) {
this.doInstall(data, win);
browser = this._getBrowserForId(data.topId);
if (browser) {
this.doInstall(data, browser);
}
break;
case "webapps-ask-uninstall":
win = this._getWindowForId(data.windowId);
if (win && win.location.href == data.from) {
this.doUninstall(data, win);
browser = this._getBrowserForId(data.topId);
if (browser) {
this.doUninstall(data, browser);
}
break;
case "webapps-launch":
@ -107,17 +115,28 @@ this.WebappManager = {
}
},
_getWindowForId: function(aId) {
let someWindow = Services.wm.getMostRecentWindow(null);
return someWindow && Services.wm.getOuterWindowWithId(aId);
_getBrowserForId: function(aId) {
let windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let window = windows.getNext();
let tabbrowser = window.gBrowser;
let foundBrowser = tabbrowser.getBrowserForOuterWindowID(aId);
if (foundBrowser) {
return foundBrowser;
}
}
let foundWindow = Services.wm.getOuterWindowWithId(aId);
if (foundWindow) {
return foundWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
}
return null;
},
doInstall: function(aData, aWindow) {
let browser = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
let chromeDoc = browser.ownerDocument;
doInstall: function(aData, aBrowser) {
let chromeDoc = aBrowser.ownerDocument;
let chromeWin = chromeDoc.defaultView;
let popupProgressContent =
chromeDoc.getElementById("webapps-install-progress-content");
@ -135,7 +154,7 @@ this.WebappManager = {
notification.remove();
notification = chromeWin.PopupNotifications.
show(browser,
show(aBrowser,
"webapps-install-progress",
bundle.getString("webapps.install.inprogress"),
"webapps-notification-icon");
@ -152,7 +171,7 @@ this.WebappManager = {
this.installations[manifestURL] = Promise.defer();
this.installations[manifestURL].promise.then(() => {
notifyInstallSuccess(aData.app, nativeApp, bundle,
PrivateBrowsingUtils.isWindowPrivate(aWindow));
PrivateBrowsingUtils.isBrowserPrivate(aBrowser));
}, (error) => {
Cu.reportError("Error installing webapp: " + error);
}).then(() => {
@ -198,20 +217,15 @@ this.WebappManager = {
let message = bundle.getFormattedString("webapps.requestInstall",
[manifest.name, host], 2);
notification = chromeWin.PopupNotifications.show(browser,
notification = chromeWin.PopupNotifications.show(aBrowser,
"webapps-install",
message,
"webapps-notification-icon",
mainAction);
},
doUninstall: function(aData, aWindow) {
let browser = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
let chromeDoc = browser.ownerDocument;
doUninstall: function(aData, aBrowser) {
let chromeDoc = aBrowser.ownerDocument;
let chromeWin = chromeDoc.defaultView;
let bundle = chromeWin.gNavigatorBundle;
@ -244,7 +258,7 @@ this.WebappManager = {
[manifest.name]);
notification = chromeWin.PopupNotifications.show(
browser, "webapps-uninstall", message,
aBrowser, "webapps-uninstall", message,
"webapps-notification-icon",
mainAction, [secondaryAction]);
}

View File

@ -588,7 +588,10 @@ let AutoCompletePopup = {
// We may not get any responses to Browser:Init if the browser element
// is torn down too quickly.
let initData = sendSyncMessage("Browser:Init");
let outerWindowID = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.outerWindowID;
let initData = sendSyncMessage("Browser:Init", {outerWindowID: outerWindowID});
if (initData.length) {
docShell.useGlobalHistory = initData[0].useGlobalHistory;
if (initData[0].initPopup) {

View File

@ -392,6 +392,15 @@
onget="return this._permanentKey;"
onset="this._permanentKey = val;"/>
<property name="outerWindowID" readonly="true">
<getter><![CDATA[
return this.contentWindow
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.outerWindowID;
]]></getter>
</property>
<field name="_lastSearchString">null</field>
<field name="_lastSearchHighlight">false</field>

View File

@ -204,6 +204,11 @@
]]></getter>
</property>
<field name="_outerWindowID">null</field>
<property name="outerWindowID"
onget="return this._outerWindowID"
readonly="true"/>
<property name="autoCompletePopup"
onget="return document.getElementById(this.getAttribute('autocompletepopup'))"
readonly="true"/>
@ -289,6 +294,7 @@
let data = aMessage.data;
switch (aMessage.name) {
case "Browser:Init":
this._outerWindowID = data.outerWindowID;
let result = {};
result.useGlobalHistory = !this.hasAttribute("disableglobalhistory");
result.initPopup = this.autoCompletePopup != null;