Bug 1353104 - use HiddenFrame.jsm to create frames for add-on sdk add-ons, r=kmag
MozReview-Commit-ID: CfR9xMPVr9H
This commit is contained in:
@@ -7,59 +7,75 @@ module.metadata = {
|
||||
"stability": "experimental"
|
||||
};
|
||||
|
||||
const { Ci, Cc } = require("chrome");
|
||||
const { make: makeWindow, getHiddenWindow } = require("../window/utils");
|
||||
const { create: makeFrame, getDocShell } = require("../frame/utils");
|
||||
const { defer } = require("../core/promise");
|
||||
const { Ci, Cc, Cu } = require("chrome");
|
||||
const { when: unload } = require("../system/unload");
|
||||
const cfxArgs = require("../test/options");
|
||||
const prefs = require("../preferences/service");
|
||||
|
||||
var addonPrincipal = Cc["@mozilla.org/systemprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
if (!prefs.get("extensions.usehiddenwindow", false)) {
|
||||
const {HiddenFrame} = require("resource:///modules/HiddenFrame.jsm", {});
|
||||
let hiddenFrame = new HiddenFrame();
|
||||
exports.window = hiddenFrame.getWindow();
|
||||
exports.ready = hiddenFrame.get();
|
||||
|
||||
var hiddenWindow = getHiddenWindow();
|
||||
// Still destroy frame on unload to claim memory back early.
|
||||
// NOTE: this doesn't seem to work and just doesn't get called. :-\
|
||||
unload(function() {
|
||||
hiddenFrame.destroy();
|
||||
hiddenFrame = null;
|
||||
});
|
||||
} else {
|
||||
const { make: makeWindow, getHiddenWindow } = require("../window/utils");
|
||||
const { create: makeFrame, getDocShell } = require("../frame/utils");
|
||||
const { defer } = require("../core/promise");
|
||||
const cfxArgs = require("../test/options");
|
||||
|
||||
if (cfxArgs.parseable) {
|
||||
console.info("hiddenWindow document.documentURI:" +
|
||||
hiddenWindow.document.documentURI);
|
||||
console.info("hiddenWindow document.readyState:" +
|
||||
hiddenWindow.document.readyState);
|
||||
var addonPrincipal = Cc["@mozilla.org/systemprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
|
||||
var hiddenWindow = getHiddenWindow();
|
||||
|
||||
if (cfxArgs.parseable) {
|
||||
console.info("hiddenWindow document.documentURI:" +
|
||||
hiddenWindow.document.documentURI);
|
||||
console.info("hiddenWindow document.readyState:" +
|
||||
hiddenWindow.document.readyState);
|
||||
}
|
||||
|
||||
// Once Bug 565388 is fixed and shipped we'll be able to make invisible,
|
||||
// permanent docShells. Meanwhile we create hidden top level window and
|
||||
// use it's docShell.
|
||||
var frame = makeFrame(hiddenWindow.document, {
|
||||
nodeName: "iframe",
|
||||
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||
allowJavascript: true,
|
||||
allowPlugins: true
|
||||
})
|
||||
var docShell = getDocShell(frame);
|
||||
var eventTarget = docShell.chromeEventHandler;
|
||||
|
||||
// We need to grant docShell system principals in order to load XUL document
|
||||
// from data URI into it.
|
||||
docShell.createAboutBlankContentViewer(addonPrincipal);
|
||||
|
||||
// Get a reference to the DOM window of the given docShell and load
|
||||
// such document into that would allow us to create XUL iframes, that
|
||||
// are necessary for hidden frames etc..
|
||||
var window = docShell.contentViewer.DOMDocument.defaultView;
|
||||
window.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
|
||||
|
||||
// Create a promise that is delivered once add-on window is interactive,
|
||||
// used by add-on runner to defer add-on loading until window is ready.
|
||||
var { promise, resolve } = defer();
|
||||
eventTarget.addEventListener("DOMContentLoaded", function(event) {
|
||||
resolve();
|
||||
}, {once: true});
|
||||
|
||||
exports.ready = promise;
|
||||
exports.window = window;
|
||||
|
||||
// Still close window on unload to claim memory back early.
|
||||
unload(function() {
|
||||
window.close()
|
||||
frame.remove();
|
||||
});
|
||||
}
|
||||
|
||||
// Once Bug 565388 is fixed and shipped we'll be able to make invisible,
|
||||
// permanent docShells. Meanwhile we create hidden top level window and
|
||||
// use it's docShell.
|
||||
var frame = makeFrame(hiddenWindow.document, {
|
||||
nodeName: "iframe",
|
||||
namespaceURI: "http://www.w3.org/1999/xhtml",
|
||||
allowJavascript: true,
|
||||
allowPlugins: true
|
||||
})
|
||||
var docShell = getDocShell(frame);
|
||||
var eventTarget = docShell.chromeEventHandler;
|
||||
|
||||
// We need to grant docShell system principals in order to load XUL document
|
||||
// from data URI into it.
|
||||
docShell.createAboutBlankContentViewer(addonPrincipal);
|
||||
|
||||
// Get a reference to the DOM window of the given docShell and load
|
||||
// such document into that would allow us to create XUL iframes, that
|
||||
// are necessary for hidden frames etc..
|
||||
var window = docShell.contentViewer.DOMDocument.defaultView;
|
||||
window.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>";
|
||||
|
||||
// Create a promise that is delivered once add-on window is interactive,
|
||||
// used by add-on runner to defer add-on loading until window is ready.
|
||||
var { promise, resolve } = defer();
|
||||
eventTarget.addEventListener("DOMContentLoaded", function(event) {
|
||||
resolve();
|
||||
}, {once: true});
|
||||
|
||||
exports.ready = promise;
|
||||
exports.window = window;
|
||||
|
||||
// Still close window on unload to claim memory back early.
|
||||
unload(function() {
|
||||
window.close()
|
||||
frame.remove();
|
||||
});
|
||||
|
||||
@@ -8,8 +8,9 @@ module.metadata = {
|
||||
};
|
||||
|
||||
const { deprecateFunction } = require("../util/deprecate");
|
||||
const { Cc, Ci } = require("chrome");
|
||||
const XMLHttpRequest = require("../addon/window").window.XMLHttpRequest;
|
||||
const { Ci, Cu } = require("chrome");
|
||||
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"]);
|
||||
|
||||
Object.defineProperties(XMLHttpRequest.prototype, {
|
||||
mozBackgroundRequest: {
|
||||
|
||||
@@ -13,7 +13,7 @@ const { Services } = require("resource://gre/modules/Services.jsm");
|
||||
const { setTimeout } = require("../timers");
|
||||
const { platform } = require("../system");
|
||||
const { getMostRecentBrowserWindow, getOwnerBrowserWindow,
|
||||
getHiddenWindow, getScreenPixelsPerCSSPixel } = require("../window/utils");
|
||||
getScreenPixelsPerCSSPixel } = require("../window/utils");
|
||||
|
||||
const { create: createFrame, swapFrameLoaders, getDocShell } = require("../frame/utils");
|
||||
const { window: addonWindow } = require("../addon/window");
|
||||
|
||||
@@ -14,11 +14,27 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const XUL_PAGE = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window%20id='win'/>";
|
||||
|
||||
const gAllHiddenFrames = new WeakSet();
|
||||
|
||||
let cleanupRegistered = false;
|
||||
function ensureCleanupRegistered() {
|
||||
if (!cleanupRegistered) {
|
||||
cleanupRegistered = true;
|
||||
Services.obs.addObserver(function() {
|
||||
for (let hiddenFrame of ChromeUtils.nondeterministicGetWeakSetKeys(gAllHiddenFrames)) {
|
||||
hiddenFrame.destroy();
|
||||
}
|
||||
}, "xpcom-shutdown", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An hidden frame object. It takes care of creating a windowless browser and
|
||||
* passing the window containing a blank XUL <window> back.
|
||||
*/
|
||||
function HiddenFrame() {}
|
||||
function HiddenFrame() {
|
||||
}
|
||||
|
||||
HiddenFrame.prototype = {
|
||||
_frame: null,
|
||||
@@ -41,6 +57,16 @@ HiddenFrame.prototype = {
|
||||
return this._deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch a sync ref to the window inside the frame (needed for the add-on SDK).
|
||||
*/
|
||||
getWindow() {
|
||||
this.get();
|
||||
this._browser.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
return this._browser.getInterface(Ci.nsIDOMWindow);
|
||||
},
|
||||
|
||||
|
||||
destroy() {
|
||||
if (this._browser) {
|
||||
if (this._listener) {
|
||||
@@ -51,14 +77,17 @@ HiddenFrame.prototype = {
|
||||
this._frame = null;
|
||||
this._deferred = null;
|
||||
|
||||
gAllHiddenFrames.delete(this);
|
||||
this._browser.close();
|
||||
this._browser = null;
|
||||
}
|
||||
},
|
||||
|
||||
_create() {
|
||||
ensureCleanupRegistered();
|
||||
this._browser = Services.appShell.createWindowlessBrowser(true);
|
||||
this._browser.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
gAllHiddenFrames.add(this);
|
||||
this._webProgress = this._browser.getInterface(Ci.nsIWebProgress);
|
||||
this._listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
|
||||
Reference in New Issue
Block a user