Bug 1357486: Part 0b - Fix inline options browser tests with OOP extensions. r?aswan
MozReview-Commit-ID: Bc4hNFmVOlw
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -107,91 +107,16 @@ XPCOMUtils.defineLazyPreferenceGetter(th
raw => raw.split(","));
XPCOMUtils.defineLazyPreferenceGetter(this, "legacyExtensionsEnabled",
PREF_LEGACY_ENABLED, true,
() => gLegacyView.refresh());
document.addEventListener("load", initialize, true);
window.addEventListener("unload", shutdown);
-class MessageDispatcher {
- constructor(target) {
- this.listeners = new Map();
- this.target = target;
- }
-
- addMessageListener(name, handler) {
- if (!this.listeners.has(name)) {
- this.listeners.set(name, new Set());
- }
-
- this.listeners.get(name).add(handler);
- }
-
- removeMessageListener(name, handler) {
- if (this.listeners.has(name)) {
- this.listeners.get(name).delete(handler);
- }
- }
-
- sendAsyncMessage(name, data) {
- for (let handler of this.listeners.get(name) || new Set()) {
- Promise.resolve().then(() => {
- handler.receiveMessage({
- name,
- data,
- target: this.target,
- });
- });
- }
- }
-}
-
-/**
- * A mock FrameMessageManager global to allow frame scripts to run in
- * non-top-level, non-remote <browser>s as if they were top-level or
- * remote.
- *
- * @param {Element} browser
- * A XUL <browser> element.
- */
-class FakeFrameMessageManager {
- constructor(browser) {
- let dispatcher = new MessageDispatcher(browser);
- let frameDispatcher = new MessageDispatcher(null);
-
- 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() {
- return browser.contentWindow;
- },
-
- get docShell() {
- return browser.docShell;
- },
-
- addEventListener: bind(browser, "addEventListener"),
- removeEventListener: bind(browser, "removeEventListener"),
-
- sendAsyncMessage: bind(dispatcher, "sendAsyncMessage"),
- addMessageListener: bind(frameDispatcher, "addMessageListener"),
- removeMessageListener: bind(frameDispatcher, "removeMessageListener"),
- }
- }
-
- loadFrameScript(url) {
- Services.scriptloader.loadSubScript(url, Object.create(this.frame));
- }
-}
-
function promiseEvent(event, target, capture = false) {
return new Promise(resolve => {
target.addEventListener(event, resolve, {capture, once: true});
});
}
var gPendingInitializations = 1;
Object.defineProperty(this, "gIsInitializing", {
@@ -3782,16 +3707,17 @@ var gDetailView = {
}
},
async createOptionsBrowser(parentNode) {
let browser = document.createElement("browser");
browser.setAttribute("type", "content");
browser.setAttribute("disableglobalhistory", "true");
browser.setAttribute("class", "inline-options-browser");
+ browser.setAttribute("forcemessagemanager", "true");
let {optionsURL} = this._addon;
let remote = !E10SUtils.canLoadURIInProcess(optionsURL, Services.appinfo.PROCESS_TYPE_DEFAULT);
let readyPromise;
if (remote) {
browser.setAttribute("remote", "true");
browser.setAttribute("remoteType", E10SUtils.EXTENSION_REMOTE_TYPE);
@@ -3801,31 +3727,29 @@ var gDetailView = {
}
parentNode.appendChild(browser);
// Force bindings to apply synchronously.
browser.clientTop;
await readyPromise;
- if (remote) {
- ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
- }
+ ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
return new Promise(resolve => {
let messageListener = {
receiveMessage({name, data}) {
if (name === "Extension:BrowserResized")
browser.style.height = `${data.height}px`;
else if (name === "Extension:BrowserContentLoaded")
resolve(browser);
},
};
- let mm = browser.messageManager || new FakeFrameMessageManager(browser);
+ let mm = browser.messageManager;
mm.loadFrameScript("chrome://extensions/content/ext-browser-content.js",
false);
mm.addMessageListener("Extension:BrowserContentLoaded", messageListener);
mm.addMessageListener("Extension:BrowserResized", messageListener);
let browserOptions = {
fixedWidth: true,
isInline: true,
--- a/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_browser.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_inlinesettings_browser.js
@@ -1,16 +1,18 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/* globals TestUtils */
var {Extension} = Components.utils.import("resource://gre/modules/Extension.jsm", {});
+Components.utils.import("resource://testing-common/ContentTask.jsm", {});
+
var gAddon;
var gOtherAddon;
var gManagerWindow;
var gCategoryUtilities;
function installAddon(details) {
let id = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator)
.generateUUID().number;
@@ -91,65 +93,74 @@ async function openDetailsBrowser(addonI
is(gManagerWindow.gViewController.currentViewId,
`addons://detail/${encodeURIComponent(addonId)}/preferences`,
"Current view should scroll to preferences");
var browser = gManagerWindow.document.querySelector(
"#detail-grid > rows > .inline-options-browser");
var rows = browser.parentNode;
+ let url = await ContentTask.spawn(browser, {}, () => content.location.href);
+
ok(browser, "Grid should have a browser child");
is(browser.localName, "browser", "Grid should have a browser child");
- is(browser.currentURI.spec, addon.mAddon.optionsURL, "Browser has the expected options URL loaded")
+ is(url, addon.mAddon.optionsURL, "Browser has the expected options URL loaded")
is(browser.clientWidth, rows.clientWidth,
"Browser should be the same width as its parent node");
button = gManagerWindow.document.getElementById("detail-prefs-btn");
is_element_hidden(button, "Preferences button should not be visible");
return browser;
}
add_task(async function test_inline_browser_addon() {
let browser = await openDetailsBrowser(gAddon.id);
- let body = browser.contentDocument.body;
+ function checkHeights(expected) {
+ let {clientHeight} = browser;
+ return ContentTask.spawn(browser, {expected, clientHeight}, ({expected, clientHeight}) => {
+ let {body} = content.document;
- function checkHeights(expected) {
- is(body.clientHeight, expected, `Document body should be ${expected}px tall`);
- is(body.clientHeight, body.scrollHeight,
- "Document body should be tall enough to fit its contents");
+ is(body.clientHeight, expected, `Document body should be ${expected}px tall`);
+ is(body.clientHeight, body.scrollHeight,
+ "Document body should be tall enough to fit its contents");
- let heightDiff = browser.clientHeight - expected;
- ok(heightDiff >= 0 && heightDiff < 50,
- `Browser should be slightly taller than the document body (${browser.clientHeight} vs. ${expected})`);
+ let heightDiff = clientHeight - expected;
+ ok(heightDiff >= 0 && heightDiff < 50,
+ `Browser should be slightly taller than the document body (${clientHeight} vs. ${expected})`);
+ });
}
// Delay long enough to avoid hitting our resize rate limit.
let delay = () => new Promise(resolve => setTimeout(resolve, 300));
await delay();
- checkHeights(300);
+ await checkHeights(300);
info("Increase the document height, and expect the browser to grow correspondingly");
- body.classList.toggle("bigger");
+ await ContentTask.spawn(browser, null, () => {
+ content.document.body.classList.toggle("bigger");
+ });
await delay();
- checkHeights(600);
+ await checkHeights(600);
info("Decrease the document height, and expect the browser to shrink correspondingly");
- body.classList.toggle("bigger");
+ await ContentTask.spawn(browser, null, () => {
+ content.document.body.classList.toggle("bigger");
+ });
await delay();
- checkHeights(300);
+ await checkHeights(300);
await new Promise(resolve =>
gCategoryUtilities.openType("extension", resolve));
browser = gManagerWindow.document.querySelector(
".inline-options-browser");
is(browser, null, "Options browser should be removed from the document");
--- a/toolkit/mozapps/extensions/test/browser/browser_webext_options.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_webext_options.js
@@ -1,12 +1,14 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
+Components.utils.import("resource://testing-common/ContentTask.jsm", {});
+
// Wrapper to run a test that consists of:
// 1. opening the add-ons manager viewing the list of extensions
// 2. installing an extension (using the provider installer callable)
// 3. opening the preferences panel for the new extension and verifying
// that it opens cleanly
async function runTest(installer) {
let mgrWindow = await open_manager("addons://list/extension");
@@ -26,19 +28,21 @@ async function runTest(installer) {
is(mgrWindow.gViewController.currentViewId,
`addons://detail/${encodeURIComponent(id)}/preferences`,
"Current view should scroll to preferences");
var browser = mgrWindow.document.querySelector("#detail-grid > rows > .inline-options-browser");
var rows = browser.parentNode;
+ let url = await ContentTask.spawn(browser, {}, () => content.location.href);
+
ok(browser, "Grid should have a browser child");
is(browser.localName, "browser", "Grid should have a browser child");
- is(browser.currentURI.spec, element.mAddon.optionsURL, "Browser has the expected options URL loaded")
+ is(url, element.mAddon.optionsURL, "Browser has the expected options URL loaded")
is(browser.clientWidth, rows.clientWidth,
"Browser should be the same width as its parent node");
button = mgrWindow.document.getElementById("detail-prefs-btn");
is_element_hidden(button, "Preferences button should not be visible");
await close_manager(mgrWindow);