|
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 |
|
5 'use strict'; |
|
6 |
|
7 module.metadata = { |
|
8 "stability": "experimental" |
|
9 }; |
|
10 |
|
11 const { Ci } = require("chrome"); |
|
12 const XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; |
|
13 |
|
14 function eventTarget(frame) { |
|
15 return getDocShell(frame).chromeEventHandler; |
|
16 } |
|
17 exports.eventTarget = eventTarget; |
|
18 |
|
19 function getDocShell(frame) { |
|
20 let { frameLoader } = frame.QueryInterface(Ci.nsIFrameLoaderOwner); |
|
21 return frameLoader && frameLoader.docShell; |
|
22 } |
|
23 exports.getDocShell = getDocShell; |
|
24 |
|
25 /** |
|
26 * Creates a XUL `browser` element in a privileged document. |
|
27 * @params {nsIDOMDocument} document |
|
28 * @params {String} options.type |
|
29 * By default is 'content' for possible values see: |
|
30 * https://developer.mozilla.org/en/XUL/iframe#a-browser.type |
|
31 * @params {String} options.uri |
|
32 * URI of the document to be loaded into created frame. |
|
33 * @params {Boolean} options.remote |
|
34 * If `true` separate process will be used for this frame, also in such |
|
35 * case all the following options are ignored. |
|
36 * @params {Boolean} options.allowAuth |
|
37 * Whether to allow auth dialogs. Defaults to `false`. |
|
38 * @params {Boolean} options.allowJavascript |
|
39 * Whether to allow Javascript execution. Defaults to `false`. |
|
40 * @params {Boolean} options.allowPlugins |
|
41 * Whether to allow plugin execution. Defaults to `false`. |
|
42 */ |
|
43 function create(target, options) { |
|
44 target = target instanceof Ci.nsIDOMDocument ? target.documentElement : |
|
45 target instanceof Ci.nsIDOMWindow ? target.document.documentElement : |
|
46 target; |
|
47 options = options || {}; |
|
48 let remote = options.remote || false; |
|
49 let namespaceURI = options.namespaceURI || XUL; |
|
50 let isXUL = namespaceURI === XUL; |
|
51 let nodeName = isXUL && options.browser ? 'browser' : 'iframe'; |
|
52 let document = target.ownerDocument; |
|
53 |
|
54 let frame = document.createElementNS(namespaceURI, nodeName); |
|
55 // Type="content" is mandatory to enable stuff here: |
|
56 // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1776 |
|
57 frame.setAttribute('type', options.type || 'content'); |
|
58 frame.setAttribute('src', options.uri || 'about:blank'); |
|
59 |
|
60 target.appendChild(frame); |
|
61 |
|
62 // Load in separate process if `options.remote` is `true`. |
|
63 // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1347 |
|
64 if (remote) { |
|
65 if (isXUL) { |
|
66 // We remove XBL binding to avoid execution of code that is not going to |
|
67 // work because browser has no docShell attribute in remote mode |
|
68 // (for example) |
|
69 frame.setAttribute('style', '-moz-binding: none;'); |
|
70 frame.setAttribute('remote', 'true'); |
|
71 } |
|
72 else { |
|
73 frame.QueryInterface(Ci.nsIMozBrowserFrame); |
|
74 frame.createRemoteFrameLoader(null); |
|
75 } |
|
76 } |
|
77 |
|
78 |
|
79 |
|
80 // If browser is remote it won't have a `docShell`. |
|
81 if (!remote) { |
|
82 let docShell = getDocShell(frame); |
|
83 docShell.allowAuth = options.allowAuth || false; |
|
84 docShell.allowJavascript = options.allowJavascript || false; |
|
85 docShell.allowPlugins = options.allowPlugins || false; |
|
86 |
|
87 // Control whether the document can move/resize the window. Requires |
|
88 // recently added platform capability, so we test to avoid exceptions |
|
89 // in cases where capability is not present yet. |
|
90 if ("allowWindowControl" in docShell && "allowWindowControl" in options) |
|
91 docShell.allowWindowControl = !!options.allowWindowControl; |
|
92 } |
|
93 |
|
94 return frame; |
|
95 } |
|
96 exports.create = create; |
|
97 |
|
98 function swapFrameLoaders(from, to) |
|
99 from.QueryInterface(Ci.nsIFrameLoaderOwner).swapFrameLoaders(to) |
|
100 exports.swapFrameLoaders = swapFrameLoaders; |