Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * This file is part of Adblock Plus <http://adblockplus.org/>, | |
3 * Copyright (C) 2006-2014 Eyeo GmbH | |
4 * | |
5 * Adblock Plus is free software: you can redistribute it and/or modify | |
6 * it under the terms of the GNU General Public License version 3 as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * Adblock Plus is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License | |
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
16 */ | |
17 | |
18 (function(global) | |
19 { | |
20 const Ci = Components.interfaces; | |
21 | |
22 Object.defineProperty(global, "Page", { | |
Sebastian Noack
2015/01/07 10:27:52
We only expose Page objects in the background page
Wladimir Palant
2015/01/07 16:36:49
MessageProxy._handleRequest() below needs to use *
Sebastian Noack
2015/01/07 17:00:39
I'm not sure if I correctly understand the problem
Wladimir Palant
2015/01/07 19:01:19
Yes, the way this is implemented in Safari the sen
| |
23 get: function() | |
24 { | |
25 delete this.Page; | |
26 this.Page = (typeof require == "function" ? | |
27 require("ext_background").Page : | |
28 function() {}); | |
29 return this.Page; | |
30 }, | |
31 configurable: true | |
32 }); | |
33 | |
34 function getSender(origin) | |
35 { | |
36 if (origin instanceof Ci.nsIDOMXULElement) | |
37 return origin.messageManager; | |
38 else if (origin instanceof Ci.nsIMessageSender) | |
39 return origin; | |
40 else | |
41 return null; | |
42 } | |
43 | |
44 function MessageProxy(messageManager, messageTarget) | |
45 { | |
46 this._messageManager = messageManager; | |
47 this._messageTarget = messageTarget; | |
48 this._callbacks = new Map(); | |
49 this._responseCallbackCounter = 0; | |
50 | |
51 this._handleRequest = this._handleRequest.bind(this); | |
52 this._handleResponse = this._handleResponse.bind(this); | |
53 this._messageManager.addMessageListener("AdblockPlus:Message", this._handleR equest); | |
54 this._messageManager.addMessageListener("AdblockPlus:Response", this._handle Response); | |
55 } | |
56 MessageProxy.prototype = { | |
57 _disconnect: function() | |
58 { | |
59 this._messageManager.removeMessageListener("AdblockPlus:Message", this._ha ndleRequest); | |
60 this._messageManager.removeMessageListener("AdblockPlus:Response", this._h andleResponse); | |
61 }, | |
62 | |
63 _sendResponse: function(sender, callbackId, response) | |
64 { | |
65 this._responseSent = true; | |
66 | |
67 if (sender instanceof Ci.nsIMessageSender) | |
68 { | |
69 sender.sendAsyncMessage("AdblockPlus:Response", { | |
70 callbackId: callbackId, | |
71 responseSent: typeof response != "undefined", | |
72 payload: response | |
73 }); | |
74 } | |
75 }, | |
76 | |
77 _handleRequest: function(message) | |
78 { | |
79 var sender = getSender(message.target); | |
80 var request = message.data; | |
81 var sendResponse; | |
82 if (sender && "callbackId" in request) | |
83 sendResponse = this._sendResponse.bind(this, sender, request.callbackId) ; | |
84 else | |
85 sendResponse = function() {}; | |
86 | |
87 this._responseSent = false; | |
88 var result = this._messageTarget._dispatch(request.payload, { | |
89 page: new Page(sender) | |
90 }, sendResponse); | |
91 if (!result && !this._responseSent) | |
92 sendResponse(undefined); | |
93 }, | |
94 | |
95 _handleResponse: function(message) | |
96 { | |
97 var response = message.data; | |
98 var callback = this._callbacks.get(response.callbackId); | |
99 if (callback) | |
100 { | |
101 this._callbacks.delete(response.callbackId); | |
102 if (response.responseSent) | |
103 callback(response.payload); | |
104 } | |
105 }, | |
106 | |
107 sendMessage: function(message, responseCallback) | |
108 { | |
109 if (!(this._messageManager instanceof Ci.nsIMessageSender)) | |
110 throw new Error("Not implemented"); | |
111 | |
112 var request = { | |
113 payload: message | |
114 }; | |
115 if (responseCallback) | |
116 { | |
117 request.callbackId = ++this._responseCallbackCounter; | |
118 this._callbacks.set(request.callbackId, responseCallback); | |
119 } | |
120 | |
121 this._messageManager.sendAsyncMessage("AdblockPlus:Message", request); | |
122 } | |
123 }; | |
124 | |
125 function EventTarget(cancelable) | |
Sebastian Noack
2015/01/07 10:27:52
The argument is unused.
| |
126 { | |
127 this._listeners = []; | |
128 }; | |
129 EventTarget.prototype = { | |
130 addListener: function(listener) | |
131 { | |
132 if (this._listeners.indexOf(listener) == -1) | |
133 this._listeners.push(listener); | |
134 }, | |
135 removeListener: function(listener) | |
136 { | |
137 var idx = this._listeners.indexOf(listener); | |
138 if (idx != -1) | |
139 this._listeners.splice(idx, 1); | |
140 }, | |
141 _dispatch: function() | |
142 { | |
143 var result = null; | |
144 | |
145 for (var i = 0; i < this._listeners.length; i++) | |
146 result = this._listeners[i].apply(null, arguments); | |
147 | |
148 return result; | |
149 } | |
150 }; | |
151 | |
152 if (typeof exports == "object") | |
153 { | |
Sebastian Noack
2015/01/07 10:27:52
What is this branch good for?
Wladimir Palant
2015/01/07 16:36:49
This file is included either as CommonJS module (b
Sebastian Noack
2015/01/07 17:00:39
Why not |exports = ext|?
Wladimir Palant
2015/01/07 19:01:19
Surprisingly enough, that actually works with our
| |
154 exports.MessageProxy = MessageProxy; | |
155 exports.EventTarget = EventTarget; | |
156 exports.getSender = getSender; | |
157 } | |
158 else | |
159 { | |
160 if (!global.ext) | |
161 global.ext = {}; | |
162 global.ext._MessageProxy = MessageProxy; | |
163 global.ext._EventTarget = EventTarget; | |
164 } | |
165 })(this); | |
OLD | NEW |