|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 "use strict"; |
|
5 |
|
6 module.metadata = { |
|
7 "stability": "experimental" |
|
8 }; |
|
9 |
|
10 const { Ci, Cc } = require("chrome"); |
|
11 const { make: makeWindow, getHiddenWindow } = require("../window/utils"); |
|
12 const { create: makeFrame, getDocShell } = require("../frame/utils"); |
|
13 const { defer } = require("../core/promise"); |
|
14 const { when: unload } = require("../system/unload"); |
|
15 const cfxArgs = require("@test/options"); |
|
16 |
|
17 let addonPrincipal = Cc["@mozilla.org/systemprincipal;1"]. |
|
18 createInstance(Ci.nsIPrincipal); |
|
19 |
|
20 let hiddenWindow = getHiddenWindow(); |
|
21 |
|
22 if (cfxArgs.parseable) { |
|
23 console.info("hiddenWindow document.documentURI:" + |
|
24 hiddenWindow.document.documentURI); |
|
25 console.info("hiddenWindow document.readyState:" + |
|
26 hiddenWindow.document.readyState); |
|
27 } |
|
28 |
|
29 // Once Bug 565388 is fixed and shipped we'll be able to make invisible, |
|
30 // permanent docShells. Meanwhile we create hidden top level window and |
|
31 // use it's docShell. |
|
32 let frame = makeFrame(hiddenWindow.document, { |
|
33 nodeName: "iframe", |
|
34 namespaceURI: "http://www.w3.org/1999/xhtml", |
|
35 allowJavascript: true, |
|
36 allowPlugins: true |
|
37 }) |
|
38 let docShell = getDocShell(frame); |
|
39 let eventTarget = docShell.chromeEventHandler; |
|
40 |
|
41 // We need to grant docShell system principals in order to load XUL document |
|
42 // from data URI into it. |
|
43 docShell.createAboutBlankContentViewer(addonPrincipal); |
|
44 |
|
45 // Get a reference to the DOM window of the given docShell and load |
|
46 // such document into that would allow us to create XUL iframes, that |
|
47 // are necessary for hidden frames etc.. |
|
48 let window = docShell.contentViewer.DOMDocument.defaultView; |
|
49 window.location = "data:application/vnd.mozilla.xul+xml;charset=utf-8,<window/>"; |
|
50 |
|
51 // Create a promise that is delivered once add-on window is interactive, |
|
52 // used by add-on runner to defer add-on loading until window is ready. |
|
53 let { promise, resolve } = defer(); |
|
54 eventTarget.addEventListener("DOMContentLoaded", function handler(event) { |
|
55 eventTarget.removeEventListener("DOMContentLoaded", handler, false); |
|
56 resolve(); |
|
57 }, false); |
|
58 |
|
59 |
|
60 |
|
61 exports.ready = promise; |
|
62 exports.window = window; |
|
63 |
|
64 // Still close window on unload to claim memory back early. |
|
65 unload(function() { |
|
66 window.close() |
|
67 frame.parentNode.removeChild(frame); |
|
68 }); |