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

Side by Side Diff: messageResponder.js

Issue 29715759: Issue 6440 - Use long-lived connections to listen to extension events (Closed)
Patch Set: Created March 6, 2018, 6:35 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « js/desktop-options.js ('k') | mobile-options.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 "softExpiration", "expires", "title", 69 "softExpiration", "expires", "title",
70 "url"], subscription); 70 "url"], subscription);
71 if (subscription instanceof SpecialSubscription) 71 if (subscription instanceof SpecialSubscription)
72 obj.filters = subscription.filters.map(convertFilter); 72 obj.filters = subscription.filters.map(convertFilter);
73 obj.isDownloading = Synchronizer.isExecuting(subscription.url); 73 obj.isDownloading = Synchronizer.isExecuting(subscription.url);
74 return obj; 74 return obj;
75 } 75 }
76 76
77 let convertFilter = convertObject.bind(null, ["text"]); 77 let convertFilter = convertObject.bind(null, ["text"]);
78 78
79 let changeListeners = new ext.PageMap(); 79 let uiPorts = new Map();
80 let listenedPreferences = Object.create(null); 80 let listenedPreferences = Object.create(null);
81 let listenedFilterChanges = Object.create(null); 81 let listenedFilterChanges = Object.create(null);
82 let messageTypes = new Map([ 82 let messageTypes = new Map([
83 ["app", "app.respond"], 83 ["app", "app.respond"],
84 ["filter", "filters.respond"], 84 ["filter", "filters.respond"],
85 ["pref", "prefs.respond"], 85 ["pref", "prefs.respond"],
86 ["subscription", "subscriptions.respond"] 86 ["subscription", "subscriptions.respond"]
87 ]); 87 ]);
88 88
89 function sendMessage(type, action, ...args) 89 function sendMessage(type, action, ...args)
90 { 90 {
91 let pages = changeListeners.keys(); 91 if (uiPorts.size == 0)
92 if (pages.length == 0)
93 return; 92 return;
94 93
95 let convertedArgs = []; 94 let convertedArgs = [];
96 for (let arg of args) 95 for (let arg of args)
97 { 96 {
98 if (arg instanceof Subscription) 97 if (arg instanceof Subscription)
99 convertedArgs.push(convertSubscription(arg)); 98 convertedArgs.push(convertSubscription(arg));
100 else if (arg instanceof Filter) 99 else if (arg instanceof Filter)
101 convertedArgs.push(convertFilter(arg)); 100 convertedArgs.push(convertFilter(arg));
102 else 101 else
103 convertedArgs.push(arg); 102 convertedArgs.push(arg);
104 } 103 }
105 104
106 for (let page of pages) 105 for (let [uiPort, filters] of uiPorts)
107 { 106 {
108 let filters = changeListeners.get(page); 107 let actions = filters.get(type);
109 let actions = filters[type];
110 if (actions && actions.indexOf(action) != -1) 108 if (actions && actions.indexOf(action) != -1)
111 { 109 {
112 page.sendMessage({ 110 uiPort.postMessage({
113 type: messageTypes.get(type), 111 type: messageTypes.get(type),
114 action, 112 action,
115 args: convertedArgs 113 args: convertedArgs
116 }); 114 });
117 } 115 }
118 } 116 }
119 } 117 }
120 118
121 function addFilterListeners(type, actions) 119 function addFilterListeners(type, actions)
122 { 120 {
123 for (let action of actions) 121 for (let action of actions)
124 { 122 {
125 let name; 123 let name;
126 if (type == "filter" && action == "loaded") 124 if (type == "filter" && action == "loaded")
127 name = "load"; 125 name = "load";
128 else 126 else
129 name = type + "." + action; 127 name = type + "." + action;
130 128
131 if (!(name in listenedFilterChanges)) 129 if (!(name in listenedFilterChanges))
132 { 130 {
133 listenedFilterChanges[name] = null; 131 listenedFilterChanges[name] = null;
134 FilterNotifier.on(name, (...args) => 132 FilterNotifier.on(name, (...args) =>
135 { 133 {
136 sendMessage(type, action, ...args); 134 sendMessage(type, action, args[0]);
a.giammarchi 2018/03/07 08:14:29 I understand you want to keep doors opened in the
Thomas Greiner 2018/03/07 14:05:31 Done.
137 }); 135 });
138 } 136 }
139 } 137 }
140 } 138 }
141 139
142 function getListenerFilters(page) 140 function getListenerFilters(page)
143 { 141 {
144 let listenerFilters = changeListeners.get(page); 142 let listenerFilters = changeListeners.get(page);
145 if (!listenerFilters) 143 if (!listenerFilters)
146 { 144 {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 parseInt(info.applicationVersion, 10) >= 54 204 parseInt(info.applicationVersion, 10) >= 54
207 }; 205 };
208 } 206 }
209 207
210 if (message.what == "senderId") 208 if (message.what == "senderId")
211 return sender.page.id; 209 return sender.page.id;
212 210
213 return info[message.what]; 211 return info[message.what];
214 }); 212 });
215 213
216 port.on("app.listen", (message, sender) =>
217 {
218 getListenerFilters(sender.page).app = message.filter;
219 });
220
221 port.on("app.open", (message, sender) => 214 port.on("app.open", (message, sender) =>
222 { 215 {
223 if (message.what == "options") 216 if (message.what == "options")
224 { 217 {
225 showOptions(() => 218 showOptions(() =>
226 { 219 {
227 if (!message.action) 220 if (!message.action)
228 return; 221 return;
229 222
230 sendMessage("app", message.action, ...message.args); 223 sendMessage("app", message.action, ...message.args);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 continue; 290 continue;
298 291
299 if (!(filter.text in seenFilter)) 292 if (!(filter.text in seenFilter))
300 FilterStorage.removeFilter(filter); 293 FilterStorage.removeFilter(filter);
301 } 294 }
302 } 295 }
303 296
304 return errors; 297 return errors;
305 }); 298 });
306 299
307 port.on("filters.listen", (message, sender) =>
308 {
309 getListenerFilters(sender.page).filter = message.filter;
310 addFilterListeners("filter", message.filter);
311 });
312
313 port.on("filters.remove", (message, sender) => 300 port.on("filters.remove", (message, sender) =>
314 { 301 {
315 let filter = Filter.fromText(message.text); 302 let filter = Filter.fromText(message.text);
316 let subscription = null; 303 let subscription = null;
317 if (message.subscriptionUrl) 304 if (message.subscriptionUrl)
318 subscription = Subscription.fromURL(message.subscriptionUrl); 305 subscription = Subscription.fromURL(message.subscriptionUrl);
319 306
320 if (!subscription) 307 if (!subscription)
321 FilterStorage.removeFilter(filter); 308 FilterStorage.removeFilter(filter);
322 else 309 else
323 FilterStorage.removeFilter(filter, subscription, message.index); 310 FilterStorage.removeFilter(filter, subscription, message.index);
324 }); 311 });
325 312
326 port.on("prefs.get", (message, sender) => 313 port.on("prefs.get", (message, sender) =>
327 { 314 {
328 return Prefs[message.key]; 315 return Prefs[message.key];
329 }); 316 });
330 317
331 port.on("prefs.listen", (message, sender) =>
332 {
333 getListenerFilters(sender.page).pref = message.filter;
334 for (let preference of message.filter)
335 {
336 if (!(preference in listenedPreferences))
337 {
338 listenedPreferences[preference] = null;
339 Prefs.on(preference, () =>
340 {
341 sendMessage("pref", preference, Prefs[preference]);
342 });
343 }
344 }
345 });
346
347 port.on("prefs.set", (message, sender) => 318 port.on("prefs.set", (message, sender) =>
348 { 319 {
349 if (message.key == "notifications_ignoredcategories") 320 if (message.key == "notifications_ignoredcategories")
350 return NotificationStorage.toggleIgnoreCategory("*", !!message.value); 321 return NotificationStorage.toggleIgnoreCategory("*", !!message.value);
351 322
352 return Prefs[message.key] = message.value; 323 return Prefs[message.key] = message.value;
353 }); 324 });
354 325
355 port.on("prefs.toggle", (message, sender) => 326 port.on("prefs.toggle", (message, sender) =>
356 { 327 {
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 if (message.disabledFilters) 385 if (message.disabledFilters)
415 { 386 {
416 result.disabledFilters = s.filters 387 result.disabledFilters = s.filters
417 .filter((f) => f instanceof ActiveFilter && f.disabled) 388 .filter((f) => f instanceof ActiveFilter && f.disabled)
418 .map((f) => f.text); 389 .map((f) => f.text);
419 } 390 }
420 return result; 391 return result;
421 }); 392 });
422 }); 393 });
423 394
424 port.on("subscriptions.listen", (message, sender) =>
425 {
426 getListenerFilters(sender.page).subscription = message.filter;
427 addFilterListeners("subscription", message.filter);
428 });
429
430 port.on("subscriptions.remove", (message, sender) => 395 port.on("subscriptions.remove", (message, sender) =>
431 { 396 {
432 let subscription = Subscription.fromURL(message.url); 397 let subscription = Subscription.fromURL(message.url);
433 if (subscription.url in FilterStorage.knownSubscriptions) 398 if (subscription.url in FilterStorage.knownSubscriptions)
434 FilterStorage.removeSubscription(subscription); 399 FilterStorage.removeSubscription(subscription);
435 }); 400 });
436 401
437 port.on("subscriptions.toggle", (message, sender) => 402 port.on("subscriptions.toggle", (message, sender) =>
438 { 403 {
439 let subscription = Subscription.fromURL(message.url); 404 let subscription = Subscription.fromURL(message.url);
(...skipping 15 matching lines...) Expand all
455 let {subscriptions} = FilterStorage; 420 let {subscriptions} = FilterStorage;
456 if (message.url) 421 if (message.url)
457 subscriptions = [Subscription.fromURL(message.url)]; 422 subscriptions = [Subscription.fromURL(message.url)];
458 423
459 for (let subscription of subscriptions) 424 for (let subscription of subscriptions)
460 { 425 {
461 if (subscription instanceof DownloadableSubscription) 426 if (subscription instanceof DownloadableSubscription)
462 Synchronizer.execute(subscription, true); 427 Synchronizer.execute(subscription, true);
463 } 428 }
464 }); 429 });
430
431 function listen(type, filters, newFilter)
432 {
433 switch (type)
434 {
435 case "app":
436 filters.set("app", newFilter);
437 break;
438 case "filters":
439 filters.set("filter", newFilter);
440 addFilterListeners("filter", newFilter);
441 break;
442 case "prefs":
443 filters.set("pref", newFilter);
444 for (let preference of newFilter)
445 {
446 if (!(preference in listenedPreferences))
447 {
448 listenedPreferences[preference] = null;
449 Prefs.on(preference, () =>
450 {
451 sendMessage("pref", preference, Prefs[preference]);
452 });
453 }
454 }
455 break;
456 case "subscriptions":
457 filters.set("subscription", newFilter);
458 addFilterListeners("subscription", newFilter);
459 break;
460 }
461 }
462
463 function onConnect(uiPort)
464 {
465 if (uiPort.name != "ui")
466 return;
467
468 let filters = new Map();
469 uiPorts.set(uiPort, filters);
470
471 uiPort.onDisconnect.addListener(() =>
472 {
473 uiPorts.delete(uiPort);
474 });
475
476 uiPort.onMessage.addListener((message) =>
477 {
478 let [type, action] = message.type.split(".", 2);
a.giammarchi 2018/03/07 08:14:29 WOW, first time in my life I've found a use case f
479
480 // For now we're only using long-lived connections for handling
481 // "*.listen" messages to tackle #6440
482 if (action == "listen")
483 {
484 listen(type, filters, message.filter);
485 }
486 });
487 }
488
489 browser.runtime.onConnect.addListener(onConnect);
465 })(this); 490 })(this);
OLDNEW
« no previous file with comments | « js/desktop-options.js ('k') | mobile-options.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld