Left: | ||
Right: |
OLD | NEW |
---|---|
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 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 | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
45 ]; | 45 ]; |
46 | 46 |
47 // Since we add a callback for all messaging API calls in our wrappers, | 47 // Since we add a callback for all messaging API calls in our wrappers, |
48 // Chrome assumes we're interested in the response; when there's no response, | 48 // Chrome assumes we're interested in the response; when there's no response, |
49 // it sets runtime.lastError | 49 // it sets runtime.lastError |
50 const portClosedBeforeResponseError = | 50 const portClosedBeforeResponseError = |
51 // Older versions of Chrome have a typo: | 51 // Older versions of Chrome have a typo: |
52 // https://crrev.com/c33f51726eacdcc1a487b21a13611f7eab580d6d | 52 // https://crrev.com/c33f51726eacdcc1a487b21a13611f7eab580d6d |
53 /^The message port closed before a res?ponse was received\.$/; | 53 /^The message port closed before a res?ponse was received\.$/; |
54 | 54 |
55 // This is the error Firefox throws when a message listener is not a | |
56 // function. | |
57 const invalidMessageListenerError = "Invalid listener for runtime.onMessage."; | |
58 | |
59 let messageListeners = new WeakMap(); | |
60 | |
55 function wrapAPI(api) | 61 function wrapAPI(api) |
kzar
2018/01/08 14:35:16
Since we're now wrapping the message APIs as well
Manish Jethani
2018/01/09 09:37:35
Done.
| |
56 { | 62 { |
57 let object = browser; | 63 let object = browser; |
58 let path = api.split("."); | 64 let path = api.split("."); |
59 let name = path.pop(); | 65 let name = path.pop(); |
60 | 66 |
61 for (let node of path) | 67 for (let node of path) |
62 { | 68 { |
63 object = object[node]; | 69 object = object[node]; |
64 | 70 |
65 if (!object) | 71 if (!object) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 } | 109 } |
104 else | 110 else |
105 { | 111 { |
106 resolve(result); | 112 resolve(result); |
107 } | 113 } |
108 }); | 114 }); |
109 }); | 115 }); |
110 }; | 116 }; |
111 } | 117 } |
112 | 118 |
119 function wrapMessageAPIs() | |
kzar
2018/01/08 14:35:16
Nit: `wrapRuntimeOnMessage`?
Manish Jethani
2018/01/09 09:37:35
Done.
| |
120 { | |
121 let {onMessage} = browser.runtime; | |
122 let {addListener, removeListener, hasListener} = onMessage; | |
123 | |
124 onMessage.addListener = function(listener) | |
125 { | |
126 if (typeof listener != "function") | |
Manish Jethani
2017/10/23 12:21:04
We must check the type here to be consistent with
kzar
2018/01/08 14:35:16
Acknowledged.
| |
127 throw new Error(invalidMessageListenerError); | |
128 | |
129 // Don't add the same listener twice or we end up with multiple wrappers. | |
130 if (messageListeners.has(listener)) | |
131 return; | |
132 | |
133 let wrapper = (message, sender, sendResponse) => | |
134 { | |
135 let wait = listener(message, sender, sendResponse); | |
136 | |
137 if (wait instanceof Promise) | |
138 { | |
139 wait.then(sendResponse, reason => | |
140 { | |
141 try | |
142 { | |
143 sendResponse(); | |
144 } | |
145 finally | |
146 { | |
147 // sendResponse can throw if the internal port is closed; be sure | |
Manish Jethani
2017/10/23 12:21:04
I haven't verified this, but in any case adding a
kzar
2018/01/08 14:35:16
Acknowledged.
| |
148 // to throw the original error. | |
149 throw reason; | |
150 } | |
151 }); | |
152 } | |
153 | |
154 return !!wait; | |
155 }; | |
156 | |
157 addListener.call(onMessage, wrapper); | |
158 messageListeners.set(listener, wrapper); | |
159 }; | |
160 | |
161 onMessage.removeListener = function(listener) | |
162 { | |
163 if (typeof listener != "function") | |
164 throw new Error(invalidMessageListenerError); | |
165 | |
166 let wrapper = messageListeners.get(listener); | |
167 if (wrapper) | |
168 { | |
169 removeListener.call(onMessage, wrapper); | |
170 messageListeners.delete(listener); | |
171 } | |
172 }; | |
173 | |
174 onMessage.hasListener = function(listener) | |
175 { | |
176 if (typeof listener != "function") | |
177 throw new Error(invalidMessageListenerError); | |
178 | |
179 return messageListeners.has(listener); | |
180 }; | |
181 } | |
182 | |
113 function shouldWrapAPIs() | 183 function shouldWrapAPIs() |
114 { | 184 { |
115 try | 185 try |
116 { | 186 { |
117 return !(browser.storage.local.get([]) instanceof Promise); | 187 return !(browser.storage.local.get([]) instanceof Promise); |
118 } | 188 } |
119 catch (error) | 189 catch (error) |
120 { | 190 { |
121 } | 191 } |
122 | 192 |
123 return true; | 193 return true; |
124 } | 194 } |
125 | 195 |
126 if (shouldWrapAPIs()) | 196 if (shouldWrapAPIs()) |
127 { | 197 { |
128 // Unlike Firefox and Microsoft Edge, Chrome doesn't have a "browser" object , | 198 // Unlike Firefox and Microsoft Edge, Chrome doesn't have a "browser" |
129 // but provides the extension API through the "chrome" namespace | 199 // object, but provides the extension API through the "chrome" namespace |
130 // (non-standard). | 200 // (non-standard). |
131 if (typeof browser == "undefined") | 201 if (typeof browser == "undefined") |
132 window.browser = chrome; | 202 window.browser = chrome; |
133 | 203 |
134 for (let api of asyncAPIs) | 204 for (let api of asyncAPIs) |
135 wrapAPI(api); | 205 wrapAPI(api); |
206 | |
207 wrapMessageAPIs(); | |
136 } | 208 } |
137 | 209 |
138 // Workaround since HTMLCollection, NodeList, StyleSheetList, and CSSRuleList | 210 // Workaround since HTMLCollection, NodeList, StyleSheetList, and CSSRuleList |
139 // didn't have iterator support before Chrome 51. | 211 // didn't have iterator support before Chrome 51. |
140 // https://bugs.chromium.org/p/chromium/issues/detail?id=401699 | 212 // https://bugs.chromium.org/p/chromium/issues/detail?id=401699 |
141 for (let object of [HTMLCollection, NodeList, StyleSheetList, CSSRuleList]) | 213 for (let object of [HTMLCollection, NodeList, StyleSheetList, CSSRuleList]) |
142 { | 214 { |
143 if (!(Symbol.iterator in object.prototype)) | 215 if (!(Symbol.iterator in object.prototype)) |
144 object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; | 216 object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; |
145 } | 217 } |
146 } | 218 } |
OLD | NEW |