|
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 /* This code is loaded in every child process that is started by mochitest in |
|
5 * order to be used as a replacement for UniversalXPConnect |
|
6 */ |
|
7 |
|
8 function SpecialPowers(window) { |
|
9 this.window = Components.utils.getWeakReference(window); |
|
10 this._encounteredCrashDumpFiles = []; |
|
11 this._unexpectedCrashDumpFiles = { }; |
|
12 this._crashDumpDir = null; |
|
13 this.DOMWindowUtils = bindDOMWindowUtils(window); |
|
14 Object.defineProperty(this, 'Components', { |
|
15 configurable: true, enumerable: true, get: function() { |
|
16 var win = this.window.get(); |
|
17 if (!win) |
|
18 return null; |
|
19 return getRawComponents(win); |
|
20 }}); |
|
21 this._pongHandlers = []; |
|
22 this._messageListener = this._messageReceived.bind(this); |
|
23 addMessageListener("SPPingService", this._messageListener); |
|
24 } |
|
25 |
|
26 SpecialPowers.prototype = new SpecialPowersAPI(); |
|
27 |
|
28 SpecialPowers.prototype.toString = function() { return "[SpecialPowers]"; }; |
|
29 SpecialPowers.prototype.sanityCheck = function() { return "foo"; }; |
|
30 |
|
31 // This gets filled in in the constructor. |
|
32 SpecialPowers.prototype.DOMWindowUtils = undefined; |
|
33 SpecialPowers.prototype.Components = undefined; |
|
34 |
|
35 SpecialPowers.prototype._sendSyncMessage = function(msgname, msg) { |
|
36 return sendSyncMessage(msgname, msg); |
|
37 }; |
|
38 |
|
39 SpecialPowers.prototype._sendAsyncMessage = function(msgname, msg) { |
|
40 sendAsyncMessage(msgname, msg); |
|
41 }; |
|
42 |
|
43 SpecialPowers.prototype._addMessageListener = function(msgname, listener) { |
|
44 addMessageListener(msgname, listener); |
|
45 }; |
|
46 |
|
47 SpecialPowers.prototype._removeMessageListener = function(msgname, listener) { |
|
48 removeMessageListener(msgname, listener); |
|
49 }; |
|
50 |
|
51 SpecialPowers.prototype.registerProcessCrashObservers = function() { |
|
52 addMessageListener("SPProcessCrashService", this._messageListener); |
|
53 sendSyncMessage("SPProcessCrashService", { op: "register-observer" }); |
|
54 }; |
|
55 |
|
56 SpecialPowers.prototype.unregisterProcessCrashObservers = function() { |
|
57 addMessageListener("SPProcessCrashService", this._messageListener); |
|
58 sendSyncMessage("SPProcessCrashService", { op: "unregister-observer" }); |
|
59 }; |
|
60 |
|
61 SpecialPowers.prototype._messageReceived = function(aMessage) { |
|
62 switch (aMessage.name) { |
|
63 case "SPProcessCrashService": |
|
64 if (aMessage.json.type == "crash-observed") { |
|
65 for (let e of aMessage.json.dumpIDs) { |
|
66 this._encounteredCrashDumpFiles.push(e.id + "." + e.extension); |
|
67 } |
|
68 } |
|
69 break; |
|
70 |
|
71 case "SPPingService": |
|
72 if (aMessage.json.op == "pong") { |
|
73 var handler = this._pongHandlers.shift(); |
|
74 if (handler) { |
|
75 handler(); |
|
76 } |
|
77 } |
|
78 break; |
|
79 } |
|
80 return true; |
|
81 }; |
|
82 |
|
83 SpecialPowers.prototype.quit = function() { |
|
84 sendAsyncMessage("SpecialPowers.Quit", {}); |
|
85 }; |
|
86 |
|
87 SpecialPowers.prototype.executeAfterFlushingMessageQueue = function(aCallback) { |
|
88 this._pongHandlers.push(aCallback); |
|
89 sendAsyncMessage("SPPingService", { op: "ping" }); |
|
90 }; |
|
91 |
|
92 // Expose everything but internal APIs (starting with underscores) to |
|
93 // web content. We cannot use Object.keys to view SpecialPowers.prototype since |
|
94 // we are using the functions from SpecialPowersAPI.prototype |
|
95 SpecialPowers.prototype.__exposedProps__ = {}; |
|
96 for (var i in SpecialPowers.prototype) { |
|
97 if (i.charAt(0) != "_") |
|
98 SpecialPowers.prototype.__exposedProps__[i] = "r"; |
|
99 } |
|
100 |
|
101 // Attach our API to the window. |
|
102 function attachSpecialPowersToWindow(aWindow) { |
|
103 try { |
|
104 if ((aWindow !== null) && |
|
105 (aWindow !== undefined) && |
|
106 (aWindow.wrappedJSObject) && |
|
107 !(aWindow.wrappedJSObject.SpecialPowers)) { |
|
108 aWindow.wrappedJSObject.SpecialPowers = new SpecialPowers(aWindow); |
|
109 } |
|
110 } catch(ex) { |
|
111 dump("TEST-INFO | specialpowers.js | Failed to attach specialpowers to window exception: " + ex + "\n"); |
|
112 } |
|
113 } |
|
114 |
|
115 // This is a frame script, so it may be running in a content process. |
|
116 // In any event, it is targeted at a specific "tab", so we listen for |
|
117 // the DOMWindowCreated event to be notified about content windows |
|
118 // being created in this context. |
|
119 |
|
120 function SpecialPowersManager() { |
|
121 addEventListener("DOMWindowCreated", this, false); |
|
122 } |
|
123 |
|
124 SpecialPowersManager.prototype = { |
|
125 handleEvent: function handleEvent(aEvent) { |
|
126 var window = aEvent.target.defaultView; |
|
127 attachSpecialPowersToWindow(window); |
|
128 } |
|
129 }; |
|
130 |
|
131 var specialpowersmanager = new SpecialPowersManager(); |
|
132 |
|
133 this.SpecialPowers = SpecialPowers; |
|
134 this.attachSpecialPowersToWindow = attachSpecialPowersToWindow; |