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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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, (item) => |
135 { | 133 { |
136 sendMessage(type, action, ...args); | 134 sendMessage(type, action, item); |
137 }); | 135 }); |
138 } | 136 } |
139 } | 137 } |
140 } | 138 } |
141 | 139 |
142 function getListenerFilters(page) | |
143 { | |
144 let listenerFilters = changeListeners.get(page); | |
145 if (!listenerFilters) | |
146 { | |
147 listenerFilters = Object.create(null); | |
148 changeListeners.set(page, listenerFilters); | |
149 } | |
150 return listenerFilters; | |
151 } | |
152 | |
153 function addSubscription(subscription, properties) | 140 function addSubscription(subscription, properties) |
154 { | 141 { |
155 subscription.disabled = false; | 142 subscription.disabled = false; |
156 if ("title" in properties) | 143 if ("title" in properties) |
157 subscription.title = properties.title; | 144 subscription.title = properties.title; |
158 if ("homepage" in properties) | 145 if ("homepage" in properties) |
159 subscription.homepage = properties.homepage; | 146 subscription.homepage = properties.homepage; |
160 | 147 |
161 FilterStorage.addSubscription(subscription); | 148 FilterStorage.addSubscription(subscription); |
162 if (subscription instanceof DownloadableSubscription && | 149 if (subscription instanceof DownloadableSubscription && |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 parseInt(info.applicationVersion, 10) >= 54 | 193 parseInt(info.applicationVersion, 10) >= 54 |
207 }; | 194 }; |
208 } | 195 } |
209 | 196 |
210 if (message.what == "senderId") | 197 if (message.what == "senderId") |
211 return sender.page.id; | 198 return sender.page.id; |
212 | 199 |
213 return info[message.what]; | 200 return info[message.what]; |
214 }); | 201 }); |
215 | 202 |
216 port.on("app.listen", (message, sender) => | |
217 { | |
218 getListenerFilters(sender.page).app = message.filter; | |
219 }); | |
220 | |
221 port.on("app.open", (message, sender) => | 203 port.on("app.open", (message, sender) => |
222 { | 204 { |
223 if (message.what == "options") | 205 if (message.what == "options") |
224 { | 206 { |
225 showOptions(() => | 207 showOptions(() => |
226 { | 208 { |
227 if (!message.action) | 209 if (!message.action) |
228 return; | 210 return; |
229 | 211 |
230 sendMessage("app", message.action, ...message.args); | 212 sendMessage("app", message.action, ...message.args); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 continue; | 279 continue; |
298 | 280 |
299 if (!(filter.text in seenFilter)) | 281 if (!(filter.text in seenFilter)) |
300 FilterStorage.removeFilter(filter); | 282 FilterStorage.removeFilter(filter); |
301 } | 283 } |
302 } | 284 } |
303 | 285 |
304 return errors; | 286 return errors; |
305 }); | 287 }); |
306 | 288 |
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) => | 289 port.on("filters.remove", (message, sender) => |
314 { | 290 { |
315 let filter = Filter.fromText(message.text); | 291 let filter = Filter.fromText(message.text); |
316 let subscription = null; | 292 let subscription = null; |
317 if (message.subscriptionUrl) | 293 if (message.subscriptionUrl) |
318 subscription = Subscription.fromURL(message.subscriptionUrl); | 294 subscription = Subscription.fromURL(message.subscriptionUrl); |
319 | 295 |
320 if (!subscription) | 296 if (!subscription) |
321 FilterStorage.removeFilter(filter); | 297 FilterStorage.removeFilter(filter); |
322 else | 298 else |
323 FilterStorage.removeFilter(filter, subscription, message.index); | 299 FilterStorage.removeFilter(filter, subscription, message.index); |
324 }); | 300 }); |
325 | 301 |
326 port.on("prefs.get", (message, sender) => | 302 port.on("prefs.get", (message, sender) => |
327 { | 303 { |
328 return Prefs[message.key]; | 304 return Prefs[message.key]; |
329 }); | 305 }); |
330 | 306 |
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) => | 307 port.on("prefs.set", (message, sender) => |
348 { | 308 { |
349 if (message.key == "notifications_ignoredcategories") | 309 if (message.key == "notifications_ignoredcategories") |
350 return NotificationStorage.toggleIgnoreCategory("*", !!message.value); | 310 return NotificationStorage.toggleIgnoreCategory("*", !!message.value); |
351 | 311 |
352 return Prefs[message.key] = message.value; | 312 return Prefs[message.key] = message.value; |
353 }); | 313 }); |
354 | 314 |
355 port.on("prefs.toggle", (message, sender) => | 315 port.on("prefs.toggle", (message, sender) => |
356 { | 316 { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 if (message.disabledFilters) | 374 if (message.disabledFilters) |
415 { | 375 { |
416 result.disabledFilters = s.filters | 376 result.disabledFilters = s.filters |
417 .filter((f) => f instanceof ActiveFilter && f.disabled) | 377 .filter((f) => f instanceof ActiveFilter && f.disabled) |
418 .map((f) => f.text); | 378 .map((f) => f.text); |
419 } | 379 } |
420 return result; | 380 return result; |
421 }); | 381 }); |
422 }); | 382 }); |
423 | 383 |
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) => | 384 port.on("subscriptions.remove", (message, sender) => |
431 { | 385 { |
432 let subscription = Subscription.fromURL(message.url); | 386 let subscription = Subscription.fromURL(message.url); |
433 if (subscription.url in FilterStorage.knownSubscriptions) | 387 if (subscription.url in FilterStorage.knownSubscriptions) |
434 FilterStorage.removeSubscription(subscription); | 388 FilterStorage.removeSubscription(subscription); |
435 }); | 389 }); |
436 | 390 |
437 port.on("subscriptions.toggle", (message, sender) => | 391 port.on("subscriptions.toggle", (message, sender) => |
438 { | 392 { |
439 let subscription = Subscription.fromURL(message.url); | 393 let subscription = Subscription.fromURL(message.url); |
(...skipping 15 matching lines...) Expand all Loading... |
455 let {subscriptions} = FilterStorage; | 409 let {subscriptions} = FilterStorage; |
456 if (message.url) | 410 if (message.url) |
457 subscriptions = [Subscription.fromURL(message.url)]; | 411 subscriptions = [Subscription.fromURL(message.url)]; |
458 | 412 |
459 for (let subscription of subscriptions) | 413 for (let subscription of subscriptions) |
460 { | 414 { |
461 if (subscription instanceof DownloadableSubscription) | 415 if (subscription instanceof DownloadableSubscription) |
462 Synchronizer.execute(subscription, true); | 416 Synchronizer.execute(subscription, true); |
463 } | 417 } |
464 }); | 418 }); |
| 419 |
| 420 function listen(type, filters, newFilter) |
| 421 { |
| 422 switch (type) |
| 423 { |
| 424 case "app": |
| 425 filters.set("app", newFilter); |
| 426 break; |
| 427 case "filters": |
| 428 filters.set("filter", newFilter); |
| 429 addFilterListeners("filter", newFilter); |
| 430 break; |
| 431 case "prefs": |
| 432 filters.set("pref", newFilter); |
| 433 for (let preference of newFilter) |
| 434 { |
| 435 if (!(preference in listenedPreferences)) |
| 436 { |
| 437 listenedPreferences[preference] = null; |
| 438 Prefs.on(preference, () => |
| 439 { |
| 440 sendMessage("pref", preference, Prefs[preference]); |
| 441 }); |
| 442 } |
| 443 } |
| 444 break; |
| 445 case "subscriptions": |
| 446 filters.set("subscription", newFilter); |
| 447 addFilterListeners("subscription", newFilter); |
| 448 break; |
| 449 } |
| 450 } |
| 451 |
| 452 function onConnect(uiPort) |
| 453 { |
| 454 if (uiPort.name != "ui") |
| 455 return; |
| 456 |
| 457 let filters = new Map(); |
| 458 uiPorts.set(uiPort, filters); |
| 459 |
| 460 uiPort.onDisconnect.addListener(() => |
| 461 { |
| 462 uiPorts.delete(uiPort); |
| 463 }); |
| 464 |
| 465 uiPort.onMessage.addListener((message) => |
| 466 { |
| 467 let [type, action] = message.type.split(".", 2); |
| 468 |
| 469 // For now we're only using long-lived connections for handling |
| 470 // "*.listen" messages to tackle #6440 |
| 471 if (action == "listen") |
| 472 { |
| 473 listen(type, filters, message.filter); |
| 474 } |
| 475 }); |
| 476 } |
| 477 |
| 478 browser.runtime.onConnect.addListener(onConnect); |
465 })(this); | 479 })(this); |
OLD | NEW |