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: function ChromePowers(window) { michael@0: this.window = Components.utils.getWeakReference(window); michael@0: michael@0: // In the case of browser-chrome tests, we are running as a [ChromeWindow] michael@0: // and we have no window.QueryInterface available, content.window is what we need michael@0: if (typeof(window) == "ChromeWindow" && typeof(content.window) == "Window") { michael@0: this.DOMWindowUtils = bindDOMWindowUtils(content.window); michael@0: this.window = Components.utils.getWeakReference(content.window); michael@0: } else { michael@0: this.DOMWindowUtils = bindDOMWindowUtils(window); michael@0: } michael@0: michael@0: this.spObserver = new SpecialPowersObserverAPI(); michael@0: } michael@0: michael@0: ChromePowers.prototype = new SpecialPowersAPI(); michael@0: michael@0: ChromePowers.prototype.toString = function() { return "[ChromePowers]"; }; michael@0: ChromePowers.prototype.sanityCheck = function() { return "foo"; }; michael@0: michael@0: // This gets filled in in the constructor. michael@0: ChromePowers.prototype.DOMWindowUtils = undefined; michael@0: michael@0: ChromePowers.prototype._sendSyncMessage = function(type, msg) { michael@0: var aMessage = {'name':type, 'json': msg}; michael@0: return [this._receiveMessage(aMessage)]; michael@0: }; michael@0: michael@0: ChromePowers.prototype._sendAsyncMessage = function(type, msg) { michael@0: var aMessage = {'name':type, 'json': msg}; michael@0: this._receiveMessage(aMessage); michael@0: }; michael@0: michael@0: ChromePowers.prototype.registerProcessCrashObservers = function() { michael@0: this._sendSyncMessage("SPProcessCrashService", { op: "register-observer" }); michael@0: }; michael@0: michael@0: ChromePowers.prototype.unregisterProcessCrashObservers = function() { michael@0: this._sendSyncMessage("SPProcessCrashService", { op: "unregister-observer" }); michael@0: }; michael@0: michael@0: ChromePowers.prototype._receiveMessage = function(aMessage) { michael@0: switch (aMessage.name) { michael@0: case "SpecialPowers.Quit": michael@0: let appStartup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup); michael@0: appStartup.quit(Ci.nsIAppStartup.eForceQuit); michael@0: break; michael@0: case "SPProcessCrashService": michael@0: if (aMessage.json.op == "register-observer" || aMessage.json.op == "unregister-observer") { michael@0: // Hack out register/unregister specifically for browser-chrome leaks michael@0: break; michael@0: } else if (aMessage.type == "crash-observed") { michael@0: for (let e of msg.dumpIDs) { michael@0: this._encounteredCrashDumpFiles.push(e.id + "." + e.extension); michael@0: } michael@0: } michael@0: default: michael@0: // All calls go here, because we need to handle SPProcessCrashService calls as well michael@0: return this.spObserver._receiveMessageAPI(aMessage); michael@0: } michael@0: return undefined; // Avoid warning. michael@0: }; michael@0: michael@0: ChromePowers.prototype.quit = function() { michael@0: // We come in here as SpecialPowers.quit, but SpecialPowers is really ChromePowers. michael@0: // For some reason this. resolves to TestRunner, so using SpecialPowers michael@0: // allows us to use the ChromePowers object which we defined below. michael@0: SpecialPowers._sendSyncMessage("SpecialPowers.Quit", {}); michael@0: }; michael@0: michael@0: ChromePowers.prototype.focus = function(aWindow) { michael@0: // We come in here as SpecialPowers.focus, but SpecialPowers is really ChromePowers. michael@0: // For some reason this. resolves to TestRunner, so using SpecialPowers michael@0: // allows us to use the ChromePowers object which we defined below. michael@0: if (aWindow) michael@0: aWindow.focus(); michael@0: }; michael@0: michael@0: ChromePowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) { michael@0: aCallback(); michael@0: }; michael@0: michael@0: // Expose everything but internal APIs (starting with underscores) to michael@0: // web content. We cannot use Object.keys to view SpecialPowers.prototype since michael@0: // we are using the functions from SpecialPowersAPI.prototype michael@0: ChromePowers.prototype.__exposedProps__ = {}; michael@0: for (var i in ChromePowers.prototype) { michael@0: if (i.charAt(0) != "_") michael@0: ChromePowers.prototype.__exposedProps__[i] = "r"; michael@0: } michael@0: michael@0: if ((window.parent !== null) && michael@0: (window.parent !== undefined) && michael@0: (window.parent.wrappedJSObject.SpecialPowers) && michael@0: !(window.wrappedJSObject.SpecialPowers)) { michael@0: window.wrappedJSObject.SpecialPowers = window.parent.SpecialPowers; michael@0: } else { michael@0: window.wrappedJSObject.SpecialPowers = new ChromePowers(window); michael@0: } michael@0: