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: "use strict"; michael@0: michael@0: module.metadata = { michael@0: "stability": "experimental" michael@0: }; michael@0: michael@0: const { Cc, Ci, CC, Cu } = require('chrome'); michael@0: const systemPrincipal = CC('@mozilla.org/systemprincipal;1', 'nsIPrincipal')(); michael@0: const scriptLoader = Cc['@mozilla.org/moz/jssubscript-loader;1']. michael@0: getService(Ci.mozIJSSubScriptLoader); michael@0: const self = require('sdk/self'); michael@0: const { getTabId, getTabForContentWindow } = require('../tabs/utils'); michael@0: const { getInnerId } = require('../window/utils'); michael@0: michael@0: const { gDevToolsExtensions: { michael@0: addContentGlobal, removeContentGlobal michael@0: } } = Cu.import("resource://gre/modules/devtools/DevToolsExtensions.jsm", {}); michael@0: michael@0: /** michael@0: * Make a new sandbox that inherits given `source`'s principals. Source can be michael@0: * URI string, DOMWindow or `null` for system principals. michael@0: */ michael@0: function sandbox(target, options) { michael@0: options = options || {}; michael@0: options.metadata = options.metadata ? options.metadata : {}; michael@0: options.metadata.addonID = options.metadata.addonID ? michael@0: options.metadata.addonID : self.id; michael@0: michael@0: let sandbox = Cu.Sandbox(target || systemPrincipal, options); michael@0: Cu.setSandboxMetadata(sandbox, options.metadata); michael@0: let innerWindowID = options.metadata['inner-window-id'] michael@0: if (innerWindowID) { michael@0: addContentGlobal({ michael@0: global: sandbox, michael@0: 'inner-window-id': innerWindowID michael@0: }); michael@0: } michael@0: return sandbox; michael@0: } michael@0: exports.sandbox = sandbox; michael@0: michael@0: /** michael@0: * Evaluates given `source` in a given `sandbox` and returns result. michael@0: */ michael@0: function evaluate(sandbox, code, uri, line, version) { michael@0: return Cu.evalInSandbox(code, sandbox, version || '1.8', uri || '', line || 1); michael@0: } michael@0: exports.evaluate = evaluate; michael@0: michael@0: /** michael@0: * Evaluates code under the given `uri` in the given `sandbox`. michael@0: * michael@0: * @param {String} uri michael@0: * The URL pointing to the script to load. michael@0: * It must be a local chrome:, resource:, file: or data: URL. michael@0: */ michael@0: function load(sandbox, uri) { michael@0: if (uri.indexOf('data:') === 0) { michael@0: let source = uri.substr(uri.indexOf(',') + 1); michael@0: michael@0: return evaluate(sandbox, decodeURIComponent(source), '1.8', uri, 0); michael@0: } else { michael@0: return scriptLoader.loadSubScript(uri, sandbox, 'UTF-8'); michael@0: } michael@0: } michael@0: exports.load = load; michael@0: michael@0: /** michael@0: * Forces the given `sandbox` to be freed immediately. michael@0: */ michael@0: exports.nuke = Cu.nukeSandbox