michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: 'use strict'; michael@0: michael@0: module.metadata = { michael@0: "stability": "experimental" michael@0: }; michael@0: michael@0: const { Ci } = require("chrome"); michael@0: const XUL = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; michael@0: michael@0: function eventTarget(frame) { michael@0: return getDocShell(frame).chromeEventHandler; michael@0: } michael@0: exports.eventTarget = eventTarget; michael@0: michael@0: function getDocShell(frame) { michael@0: let { frameLoader } = frame.QueryInterface(Ci.nsIFrameLoaderOwner); michael@0: return frameLoader && frameLoader.docShell; michael@0: } michael@0: exports.getDocShell = getDocShell; michael@0: michael@0: /** michael@0: * Creates a XUL `browser` element in a privileged document. michael@0: * @params {nsIDOMDocument} document michael@0: * @params {String} options.type michael@0: * By default is 'content' for possible values see: michael@0: * https://developer.mozilla.org/en/XUL/iframe#a-browser.type michael@0: * @params {String} options.uri michael@0: * URI of the document to be loaded into created frame. michael@0: * @params {Boolean} options.remote michael@0: * If `true` separate process will be used for this frame, also in such michael@0: * case all the following options are ignored. michael@0: * @params {Boolean} options.allowAuth michael@0: * Whether to allow auth dialogs. Defaults to `false`. michael@0: * @params {Boolean} options.allowJavascript michael@0: * Whether to allow Javascript execution. Defaults to `false`. michael@0: * @params {Boolean} options.allowPlugins michael@0: * Whether to allow plugin execution. Defaults to `false`. michael@0: */ michael@0: function create(target, options) { michael@0: target = target instanceof Ci.nsIDOMDocument ? target.documentElement : michael@0: target instanceof Ci.nsIDOMWindow ? target.document.documentElement : michael@0: target; michael@0: options = options || {}; michael@0: let remote = options.remote || false; michael@0: let namespaceURI = options.namespaceURI || XUL; michael@0: let isXUL = namespaceURI === XUL; michael@0: let nodeName = isXUL && options.browser ? 'browser' : 'iframe'; michael@0: let document = target.ownerDocument; michael@0: michael@0: let frame = document.createElementNS(namespaceURI, nodeName); michael@0: // Type="content" is mandatory to enable stuff here: michael@0: // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1776 michael@0: frame.setAttribute('type', options.type || 'content'); michael@0: frame.setAttribute('src', options.uri || 'about:blank'); michael@0: michael@0: target.appendChild(frame); michael@0: michael@0: // Load in separate process if `options.remote` is `true`. michael@0: // http://mxr.mozilla.org/mozilla-central/source/content/base/src/nsFrameLoader.cpp#1347 michael@0: if (remote) { michael@0: if (isXUL) { michael@0: // We remove XBL binding to avoid execution of code that is not going to michael@0: // work because browser has no docShell attribute in remote mode michael@0: // (for example) michael@0: frame.setAttribute('style', '-moz-binding: none;'); michael@0: frame.setAttribute('remote', 'true'); michael@0: } michael@0: else { michael@0: frame.QueryInterface(Ci.nsIMozBrowserFrame); michael@0: frame.createRemoteFrameLoader(null); michael@0: } michael@0: } michael@0: michael@0: michael@0: michael@0: // If browser is remote it won't have a `docShell`. michael@0: if (!remote) { michael@0: let docShell = getDocShell(frame); michael@0: docShell.allowAuth = options.allowAuth || false; michael@0: docShell.allowJavascript = options.allowJavascript || false; michael@0: docShell.allowPlugins = options.allowPlugins || false; michael@0: michael@0: // Control whether the document can move/resize the window. Requires michael@0: // recently added platform capability, so we test to avoid exceptions michael@0: // in cases where capability is not present yet. michael@0: if ("allowWindowControl" in docShell && "allowWindowControl" in options) michael@0: docShell.allowWindowControl = !!options.allowWindowControl; michael@0: } michael@0: michael@0: return frame; michael@0: } michael@0: exports.create = create; michael@0: michael@0: function swapFrameLoaders(from, to) michael@0: from.QueryInterface(Ci.nsIFrameLoaderOwner).swapFrameLoaders(to) michael@0: exports.swapFrameLoaders = swapFrameLoaders;