Bug 1317101 - Part 7e: Load extension options pages in a remote browser. r=aswan

MozReview-Commit-ID: 963sD0DcwhT

--HG--
extra : rebase_source : 2d914c53476133d4e635998e6fbefd9d450758ea
extra : source : 1e1bfb578dcd24433d43fb67cc1f75e87ba48d21
This commit is contained in:
Kris Maglione 2016-11-16 13:24:08 -08:00
Родитель 4c0fec6cab
Коммит 73067d82f6
3 изменённых файлов: 56 добавлений и 28 удалений

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

@ -98,7 +98,7 @@ const BrowserListener = {
case "load":
if (event.target.contentWindow === content) {
// For about:addons inline <browsers>, we currently receive a load
// For about:addons inline <browser>s, we currently receive a load
// event on the <browser> element, but no load or DOMContentLoaded
// events from the content window.
sendAsyncMessage("Extension:BrowserContentLoaded", {url: content.location.href});

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

@ -13,11 +13,16 @@ var Cu = Components.utils;
var Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/addons/AddonRepository.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "E10SUtils", "resource:///modules/E10SUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionParent",
"resource://gre/modules/ExtensionParent.jsm");
const CONSTANTS = {};
Cu.import("resource://gre/modules/addons/AddonConstants.jsm", CONSTANTS);
const SIGNING_REQUIRED = CONSTANTS.REQUIRE_SIGNING ?
@ -129,9 +134,11 @@ class FakeFrameMessageManager {
let dispatcher = new MessageDispatcher(browser);
let frameDispatcher = new MessageDispatcher(null);
this.sendAsyncMessage = frameDispatcher.sendAsyncMessage.bind(frameDispatcher);
this.addMessageListener = dispatcher.addMessageListener.bind(dispatcher);
this.removeMessageListener = dispatcher.removeMessageListener.bind(dispatcher);
let bind = (object, method) => object[method].bind(object);
this.sendAsyncMessage = bind(frameDispatcher, "sendAsyncMessage");
this.addMessageListener = bind(dispatcher, "addMessageListener");
this.removeMessageListener = bind(dispatcher, "removeMessageListener");
this.frame = {
get content() {
@ -142,12 +149,12 @@ class FakeFrameMessageManager {
return browser.docShell;
},
addEventListener: browser.addEventListener.bind(browser),
removeEventListener: browser.removeEventListener.bind(browser),
addEventListener: bind(browser, "addEventListener"),
removeEventListener: bind(browser, "removeEventListener"),
sendAsyncMessage: dispatcher.sendAsyncMessage.bind(dispatcher),
addMessageListener: frameDispatcher.addMessageListener.bind(frameDispatcher),
removeMessageListener: frameDispatcher.removeMessageListener.bind(frameDispatcher),
sendAsyncMessage: bind(dispatcher, "sendAsyncMessage"),
addMessageListener: bind(frameDispatcher, "addMessageListener"),
removeMessageListener: bind(frameDispatcher, "removeMessageListener"),
}
}
@ -156,6 +163,12 @@ class FakeFrameMessageManager {
}
}
function promiseEvent(event, target, capture = false) {
return new Promise(resolve => {
target.addEventListener(event, resolve, {capture, once: true});
});
}
var gPendingInitializations = 1;
Object.defineProperty(this, "gIsInitializing", {
get: () => gPendingInitializations > 0
@ -3517,13 +3530,34 @@ var gDetailView = {
}
},
createOptionsBrowser: function(parentNode) {
createOptionsBrowser: Task.async(function*(parentNode) {
let browser = document.createElement("browser");
browser.setAttribute("type", "content");
browser.setAttribute("disableglobalhistory", "true");
browser.setAttribute("class", "inline-options-browser");
return new Promise((resolve, reject) => {
let {optionsURL} = this._addon;
let remote = !E10SUtils.canLoadURIInProcess(optionsURL, Services.appinfo.PROCESS_TYPE_DEFAULT);
let readyPromise;
if (remote) {
browser.setAttribute("remote", "true");
readyPromise = promiseEvent("XULFrameLoaderCreated", browser);
} else {
readyPromise = promiseEvent("load", browser, true);
}
parentNode.appendChild(browser);
// Force bindings to apply synchronously.
browser.clientTop;
yield readyPromise;
if (remote) {
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
}
return new Promise(resolve => {
let messageListener = {
receiveMessage({name, data}) {
if (name === "Extension:BrowserResized")
@ -3533,24 +3567,16 @@ var gDetailView = {
},
};
let onload = () => {
browser.removeEventListener("load", onload, true);
let mm = browser.messageManager || new FakeFrameMessageManager(browser);
mm.loadFrameScript("chrome://extensions/content/ext-browser-content.js",
false);
mm.addMessageListener("Extension:BrowserContentLoaded", messageListener);
mm.addMessageListener("Extension:BrowserResized", messageListener);
mm.sendAsyncMessage("Extension:InitBrowser", {fixedWidth: true});
let mm = new FakeFrameMessageManager(browser);
mm.loadFrameScript("chrome://extensions/content/ext-browser-content.js",
false);
mm.addMessageListener("Extension:BrowserContentLoaded", messageListener);
mm.addMessageListener("Extension:BrowserResized", messageListener);
mm.sendAsyncMessage("Extension:InitBrowser", {fixedWidth: true});
browser.setAttribute("src", this._addon.optionsURL);
};
browser.addEventListener("load", onload, true);
browser.addEventListener("error", reject);
parentNode.appendChild(browser);
browser.loadURI(optionsURL);
});
},
}),
getSelectedAddon: function() {
return this._addon;

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

@ -124,12 +124,14 @@ add_task(function* test_inline_browser_addon() {
let heightDiff = browser.clientHeight - expected;
ok(heightDiff >= 0 && heightDiff < 50,
"Browser should be slightly taller than the document body");
`Browser should be slightly taller than the document body (${browser.clientHeight} vs. ${expected})`);
}
// Delay long enough to avoid hitting our resize rate limit.
let delay = () => new Promise(resolve => setTimeout(resolve, 300));
yield delay();
checkHeights(300);
info("Increase the document height, and expect the browser to grow correspondingly");