Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: polyfill.js

Issue 29585594: Issue 4579 - Wrap runtime.onMessage (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Left Patch Set: Wrap removeListener and hasListener Created Oct. 23, 2017, 12:13 p.m.
Right Patch Set: Rename functions Created Jan. 9, 2018, 9:36 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 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/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 "use strict"; 18 "use strict";
19 19
20 { 20 {
21 const asyncAPIs = [ 21 const asyncAPIs = [
22 "contextMenus.removeAll", 22 "contextMenus.removeAll",
23 "devtools.panels.create", 23 "devtools.panels.create",
24 "notifications.clear", 24 "notifications.clear",
25 "notifications.create", 25 "notifications.create",
26 "runtime.getBrowserInfo",
26 "runtime.openOptionsPage", 27 "runtime.openOptionsPage",
27 "runtime.sendMessage", 28 "runtime.sendMessage",
28 "runtime.setUninstallURL", 29 "runtime.setUninstallURL",
29 "storage.local.get", 30 "storage.local.get",
30 "storage.local.remove", 31 "storage.local.remove",
31 "storage.local.set", 32 "storage.local.set",
32 "storage.managed.get", 33 "storage.managed.get",
33 "tabs.create", 34 "tabs.create",
34 "tabs.get", 35 "tabs.get",
35 "tabs.getCurrent", 36 "tabs.getCurrent",
(...skipping 15 matching lines...) Expand all
51 // Older versions of Chrome have a typo: 52 // Older versions of Chrome have a typo:
52 // https://crrev.com/c33f51726eacdcc1a487b21a13611f7eab580d6d 53 // https://crrev.com/c33f51726eacdcc1a487b21a13611f7eab580d6d
53 /^The message port closed before a res?ponse was received\.$/; 54 /^The message port closed before a res?ponse was received\.$/;
54 55
55 // This is the error Firefox throws when a message listener is not a 56 // This is the error Firefox throws when a message listener is not a
56 // function. 57 // function.
57 const invalidMessageListenerError = "Invalid listener for runtime.onMessage."; 58 const invalidMessageListenerError = "Invalid listener for runtime.onMessage.";
58 59
59 let messageListeners = new WeakMap(); 60 let messageListeners = new WeakMap();
60 61
61 function wrapAPI(api) 62 function wrapAsyncAPI(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.
62 { 63 {
63 let object = browser; 64 let object = browser;
64 let path = api.split("."); 65 let path = api.split(".");
65 let name = path.pop(); 66 let name = path.pop();
66 67
67 for (let node of path) 68 for (let node of path)
68 { 69 {
69 object = object[node]; 70 object = object[node];
70 71
71 if (!object) 72 if (!object)
72 return; 73 return;
73 } 74 }
74 75
75 let func = object[name]; 76 let func = object[name];
76 object[name] = function(...args) 77 if (!func)
78 return;
79
80 let descriptor = Object.getOwnPropertyDescriptor(object, name);
81
82 delete descriptor["get"];
83 delete descriptor["set"];
84
85 descriptor.value = function(...args)
77 { 86 {
78 let callStack = new Error().stack; 87 let callStack = new Error().stack;
79 88
80 if (typeof args[args.length - 1] == "function") 89 if (typeof args[args.length - 1] == "function")
81 return func.apply(object, args); 90 return func.apply(object, args);
82 91
83 // If the last argument is undefined, we drop it from the list assuming 92 // If the last argument is undefined, we drop it from the list assuming
84 // it stands for the optional callback. We must do this, because we have 93 // it stands for the optional callback. We must do this, because we have
85 // to replace it with our own callback. If we simply append our own 94 // to replace it with our own callback. If we simply append our own
86 // callback to the list, it won't match the signature of the function and 95 // callback to the list, it won't match the signature of the function and
(...skipping 20 matching lines...) Expand all
107 116
108 reject(error); 117 reject(error);
109 } 118 }
110 else 119 else
111 { 120 {
112 resolve(result); 121 resolve(result);
113 } 122 }
114 }); 123 });
115 }); 124 });
116 }; 125 };
117 } 126
118 127 Object.defineProperty(object, name, descriptor);
119 function wrapMessageAPIs() 128 }
kzar 2018/01/08 14:35:16 Nit: `wrapRuntimeOnMessage`?
Manish Jethani 2018/01/09 09:37:35 Done.
129
130 function wrapRuntimeOnMessage()
120 { 131 {
121 let {onMessage} = browser.runtime; 132 let {onMessage} = browser.runtime;
122 let {addListener, removeListener, hasListener} = onMessage; 133 let {addListener, removeListener, hasListener} = onMessage;
123 134
124 onMessage.addListener = function(listener) 135 onMessage.addListener = function(listener)
125 { 136 {
126 if (typeof listener != "function") 137 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); 138 throw new Error(invalidMessageListenerError);
128 139
129 // Don't add the same listener twice or we end up with multiple wrappers. 140 // Don't add the same listener twice or we end up with multiple wrappers.
130 if (messageListeners.has(listener)) 141 if (messageListeners.has(listener))
131 return; 142 return;
132 143
133 let wrapper = (message, sender, sendResponse) => 144 let wrapper = (message, sender, sendResponse) =>
134 { 145 {
135 let wait = listener(message, sender, sendResponse); 146 let wait = listener(message, sender, sendResponse);
136 147
137 if (wait instanceof Promise) 148 if (wait instanceof Promise)
138 { 149 {
139 wait.then(sendResponse, reason => 150 wait.then(sendResponse, reason =>
140 { 151 {
141 try 152 try
142 { 153 {
143 sendResponse(); 154 sendResponse();
144 } 155 }
145 finally 156 finally
146 { 157 {
147 // sendResponse can throw if the internal port is closed; be sure 158 // 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. 159 // to throw the original error.
149 throw reason; 160 throw reason;
150 } 161 }
151 }); 162 });
152 } 163 }
153 164
154 return !!wait; 165 return !!wait;
155 }; 166 };
156 167
157 addListener.call(onMessage, wrapper); 168 addListener.call(onMessage, wrapper);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 206
196 if (shouldWrapAPIs()) 207 if (shouldWrapAPIs())
197 { 208 {
198 // Unlike Firefox and Microsoft Edge, Chrome doesn't have a "browser" 209 // Unlike Firefox and Microsoft Edge, Chrome doesn't have a "browser"
199 // object, but provides the extension API through the "chrome" namespace 210 // object, but provides the extension API through the "chrome" namespace
200 // (non-standard). 211 // (non-standard).
201 if (typeof browser == "undefined") 212 if (typeof browser == "undefined")
202 window.browser = chrome; 213 window.browser = chrome;
203 214
204 for (let api of asyncAPIs) 215 for (let api of asyncAPIs)
205 wrapAPI(api); 216 wrapAsyncAPI(api);
206 217
207 wrapMessageAPIs(); 218 wrapRuntimeOnMessage();
208 } 219 }
209 220
210 // Workaround since HTMLCollection, NodeList, StyleSheetList, and CSSRuleList 221 // Workaround since HTMLCollection, NodeList, StyleSheetList, and CSSRuleList
211 // didn't have iterator support before Chrome 51. 222 // didn't have iterator support before Chrome 51.
212 // https://bugs.chromium.org/p/chromium/issues/detail?id=401699 223 // https://bugs.chromium.org/p/chromium/issues/detail?id=401699
213 for (let object of [HTMLCollection, NodeList, StyleSheetList, CSSRuleList]) 224 for (let object of [HTMLCollection, NodeList, StyleSheetList, CSSRuleList])
214 { 225 {
215 if (!(Symbol.iterator in object.prototype)) 226 if (!(Symbol.iterator in object.prototype))
216 object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 227 object.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
217 } 228 }
218 } 229 }
LEFTRIGHT
« no previous file | no next file » | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld