Left: | ||
Right: |
LEFT | RIGHT |
---|---|
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-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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 (function() | |
20 { | 21 { |
21 function EventEmitter() | 22 function EventEmitter() |
22 { | 23 { |
23 this._listeners = Object.create(null); | 24 this._listeners = Object.create(null); |
24 } | 25 } |
25 EventEmitter.prototype = { | 26 EventEmitter.prototype = { |
26 on(name, listener) | 27 on(name, listener) |
27 { | 28 { |
28 if (name in this._listeners) | 29 if (name in this._listeners) |
29 this._listeners[name].push(listener); | 30 this._listeners[name].push(listener); |
30 else | 31 else |
31 this._listeners[name] = [listener]; | 32 this._listeners[name] = [listener]; |
32 }, | 33 }, |
33 off(name, listener) | 34 off(name, listener) |
34 { | 35 { |
35 let listeners = this._listeners[name]; | 36 let listeners = this._listeners[name]; |
36 if (listeners) | 37 if (listeners) |
37 { | 38 { |
38 let idx = listeners.indexOf(listener); | 39 let idx = listeners.indexOf(listener); |
39 if (idx != -1) | 40 if (idx != -1) |
40 listeners.splice(idx, 1); | 41 listeners.splice(idx, 1); |
41 } | 42 } |
42 }, | 43 }, |
43 emit(name, ...args) | 44 emit(name, ...args) |
44 { | 45 { |
45 let listeners = this._listeners[name]; | 46 let listeners = this._listeners[name]; |
46 if (listeners) | 47 if (listeners) |
47 { | 48 { |
48 for (let i = 0; i < listeners.length; i++) | 49 for (let listener of listeners) |
49 listeners[i](...args); | 50 listener(...args); |
50 } | 51 } |
51 } | 52 } |
52 }; | 53 }; |
53 | 54 |
54 function updateFromURL(data) | 55 function updateFromURL(data) |
55 { | 56 { |
56 if (window.location.search) | 57 if (window.location.search) |
57 { | 58 { |
58 let params = window.location.search.substr(1).split("&"); | 59 let params = window.location.search.substr(1).split("&"); |
59 for (let i = 0; i < params.length; i++) | 60 |
60 { | 61 for (let param of params) |
61 let parts = params[i].split("=", 2); | 62 { |
63 let parts = param.split("=", 2); | |
62 if (parts.length == 2 && parts[0] in data) | 64 if (parts.length == 2 && parts[0] in data) |
63 data[parts[0]] = decodeURIComponent(parts[1]); | 65 data[parts[0]] = decodeURIComponent(parts[1]); |
64 } | 66 } |
65 } | 67 } |
66 } | 68 } |
67 | 69 |
68 let params = { | 70 let params = { |
69 blockedURLs: "", | 71 blockedURLs: "", |
70 filterlistsReinitialized: false, | 72 filterlistsReinitialized: false, |
71 addSubscription: false, | 73 addSubscription: false, |
(...skipping 23 matching lines...) Expand all Loading... | |
95 }; | 97 }; |
96 | 98 |
97 modules.prefs = {Prefs: new EventEmitter()}; | 99 modules.prefs = {Prefs: new EventEmitter()}; |
98 let prefs = { | 100 let prefs = { |
99 notifications_ignoredcategories: (params.showNotificationUI) ? ["*"] : [], | 101 notifications_ignoredcategories: (params.showNotificationUI) ? ["*"] : [], |
100 notifications_showui: params.showNotificationUI, | 102 notifications_showui: params.showNotificationUI, |
101 shouldShowBlockElementMenu: true, | 103 shouldShowBlockElementMenu: true, |
102 show_devtools_panel: true, | 104 show_devtools_panel: true, |
103 subscriptions_exceptionsurl: "https://easylist-downloads.adblockplus.org/exc eptionrules.txt" | 105 subscriptions_exceptionsurl: "https://easylist-downloads.adblockplus.org/exc eptionrules.txt" |
104 }; | 106 }; |
105 Object.keys(prefs).forEach(key => | 107 for (let key of Object.keys(prefs)) |
Thomas Greiner
2017/03/01 17:39:32
Detail: Mind keeping the brackets? At least in Fla
kzar
2017/03/02 04:36:01
I've opened a codereview to add the arrow-parens r
kzar
2017/03/07 12:48:29
As discussed we've decided against adding the arro
Thomas Greiner
2017/03/07 13:33:00
I appreciate that because according to Felix it's
| |
106 { | 108 { |
107 Object.defineProperty(modules.prefs.Prefs, key, { | 109 Object.defineProperty(modules.prefs.Prefs, key, { |
108 get() | 110 get() |
109 { | 111 { |
110 return prefs[key]; | 112 return prefs[key]; |
111 }, | 113 }, |
112 set(value) | 114 set(value) |
113 { | 115 { |
114 prefs[key] = value; | 116 prefs[key] = value; |
115 modules.prefs.Prefs.emit(key); | 117 modules.prefs.Prefs.emit(key); |
116 } | 118 } |
117 }); | 119 }); |
118 }); | 120 } |
119 | 121 |
120 modules.notification = { | 122 modules.notification = { |
121 Notification: { | 123 Notification: { |
122 toggleIgnoreCategory(category) | 124 toggleIgnoreCategory(category) |
123 { | 125 { |
124 let categories = prefs.notifications_ignoredcategories; | 126 let categories = prefs.notifications_ignoredcategories; |
125 let index = categories.indexOf(category); | 127 let index = categories.indexOf(category); |
126 if (index == -1) | 128 if (index == -1) |
127 categories.push(category); | 129 categories.push(category); |
128 else | 130 else |
129 categories.splice(index, 1); | 131 categories.splice(index, 1); |
130 modules.prefs.Prefs.notifications_ignoredcategories = categories; | 132 modules.prefs.Prefs.notifications_ignoredcategories = categories; |
131 } | 133 } |
132 } | 134 } |
133 }; | 135 }; |
134 | 136 |
135 /* eslint-disable object-shorthand */ | 137 function Subscription(url) |
Thomas Greiner
2017/03/01 17:39:32
Detail: What about moving the constructors outside
kzar
2017/03/07 12:48:29
I think I've already done this when addressing Seb
| |
136 modules.subscriptionClasses = { | 138 { |
137 Subscription: function(url) | 139 this.url = url; |
138 { | 140 this._disabled = false; |
139 this.url = url; | 141 this._lastDownload = 1234; |
140 this._disabled = false; | 142 this.homepage = "https://easylist.adblockplus.org/"; |
141 this._lastDownload = 1234; | 143 this.downloadStatus = params.downloadStatus; |
142 this.homepage = "https://easylist.adblockplus.org/"; | 144 } |
143 this.downloadStatus = params.downloadStatus; | 145 Subscription.prototype = |
144 }, | |
145 | |
146 SpecialSubscription: function(url) | |
147 { | |
148 this.url = url; | |
149 this.disabled = false; | |
150 this.filters = knownFilters.slice(); | |
151 } | |
152 }; | |
153 modules.subscriptionClasses.Subscription.fromURL = function(url) | |
154 { | |
155 if (url in knownSubscriptions) | |
156 return knownSubscriptions[url]; | |
157 | |
158 if (/^https?:\/\//.test(url)) | |
159 return new modules.subscriptionClasses.Subscription(url); | |
160 return new modules.subscriptionClasses.SpecialSubscription(url); | |
161 }; | |
162 /* eslint-enable object-shorthand */ | |
163 modules.subscriptionClasses.DownloadableSubscription = | |
164 modules.subscriptionClasses.Subscription; | |
165 | |
166 modules.subscriptionClasses.Subscription.prototype = | |
167 { | 146 { |
168 get disabled() | 147 get disabled() |
169 { | 148 { |
170 return this._disabled; | 149 return this._disabled; |
171 }, | 150 }, |
172 set disabled(value) | 151 set disabled(value) |
173 { | 152 { |
174 this._disabled = value; | 153 this._disabled = value; |
175 modules.filterNotifier.FilterNotifier.emit("subscription.disabled", this); | 154 modules.filterNotifier.FilterNotifier.emit("subscription.disabled", this); |
176 }, | 155 }, |
177 get lastDownload() | 156 get lastDownload() |
178 { | 157 { |
179 return this._lastDownload; | 158 return this._lastDownload; |
180 }, | 159 }, |
181 set lastDownload(value) | 160 set lastDownload(value) |
182 { | 161 { |
183 this._lastDownload = value; | 162 this._lastDownload = value; |
184 modules.filterNotifier.FilterNotifier.emit("subscription.lastDownload", | 163 modules.filterNotifier.FilterNotifier.emit("subscription.lastDownload", |
185 this); | 164 this); |
186 } | 165 } |
187 }; | 166 }; |
188 | 167 Subscription.fromURL = function(url) |
168 { | |
169 if (url in knownSubscriptions) | |
170 return knownSubscriptions[url]; | |
171 | |
172 if (/^https?:\/\//.test(url)) | |
173 return new modules.subscriptionClasses.Subscription(url); | |
174 return new modules.subscriptionClasses.SpecialSubscription(url); | |
175 }; | |
176 | |
177 function SpecialSubscription(url) | |
178 { | |
179 this.url = url; | |
180 this.disabled = false; | |
181 this.filters = knownFilters.slice(); | |
182 } | |
183 | |
184 modules.subscriptionClasses = { | |
185 Subscription, | |
186 SpecialSubscription, | |
187 DownloadableSubscription: Subscription | |
188 }; | |
189 | 189 |
190 modules.filterStorage = { | 190 modules.filterStorage = { |
191 FilterStorage: { | 191 FilterStorage: { |
192 get subscriptions() | 192 get subscriptions() |
193 { | 193 { |
194 let subscriptions = []; | 194 let subscriptions = []; |
195 for (let url in modules.filterStorage.FilterStorage.knownSubscriptions) | 195 for (let url in modules.filterStorage.FilterStorage.knownSubscriptions) |
196 { | 196 { |
197 subscriptions.push( | 197 subscriptions.push( |
198 modules.filterStorage.FilterStorage.knownSubscriptions[url] | 198 modules.filterStorage.FilterStorage.knownSubscriptions[url] |
199 ); | 199 ); |
200 } | 200 } |
201 return subscriptions; | 201 return subscriptions; |
202 }, | 202 }, |
203 | 203 |
204 get knownSubscriptions() | 204 get knownSubscriptions() |
205 { | 205 { |
206 return knownSubscriptions; | 206 return knownSubscriptions; |
207 }, | 207 }, |
208 | 208 |
209 addSubscription(subscription) | 209 addSubscription(subscription) |
210 { | 210 { |
211 let {fromURL} = modules.subscriptionClasses.Subscription; | 211 let {fromURL} = Subscription; |
212 let {FilterStorage} = modules.filterStorage; | 212 let {FilterStorage} = modules.filterStorage; |
213 | 213 |
214 if (!(subscription.url in FilterStorage.knownSubscriptions)) | 214 if (!(subscription.url in FilterStorage.knownSubscriptions)) |
215 { | 215 { |
216 knownSubscriptions[subscription.url] = fromURL(subscription.url); | 216 knownSubscriptions[subscription.url] = fromURL(subscription.url); |
217 modules.filterNotifier.FilterNotifier.emit("subscription.added", | 217 modules.filterNotifier.FilterNotifier.emit("subscription.added", |
218 subscription); | 218 subscription); |
219 } | 219 } |
220 }, | 220 }, |
221 | 221 |
222 removeSubscription(subscription) | 222 removeSubscription(subscription) |
223 { | 223 { |
224 let {FilterStorage} = modules.filterStorage; | 224 let {FilterStorage} = modules.filterStorage; |
225 | 225 |
226 if (subscription.url in FilterStorage.knownSubscriptions) | 226 if (subscription.url in FilterStorage.knownSubscriptions) |
227 { | 227 { |
228 delete knownSubscriptions[subscription.url]; | 228 delete knownSubscriptions[subscription.url]; |
229 modules.filterNotifier.FilterNotifier.emit("subscription.removed", | 229 modules.filterNotifier.FilterNotifier.emit("subscription.removed", |
230 subscription); | 230 subscription); |
231 } | 231 } |
232 }, | 232 }, |
233 | 233 |
234 addFilter(filter) | 234 addFilter(filter) |
235 { | 235 { |
236 for (let i = 0; i < customSubscription.filters.length; i++) | 236 for (let customFilter of customSubscription.filters) |
237 { | 237 { |
238 if (customSubscription.filters[i].text == filter.text) | 238 if (customFilter.text == filter.text) |
239 return; | 239 return; |
240 } | 240 } |
241 customSubscription.filters.push(filter); | 241 customSubscription.filters.push(filter); |
242 modules.filterNotifier.FilterNotifier.emit("filter.added", filter); | 242 modules.filterNotifier.FilterNotifier.emit("filter.added", filter); |
243 }, | 243 }, |
244 | 244 |
245 removeFilter(filter) | 245 removeFilter(filter) |
246 { | 246 { |
247 for (let i = 0; i < customSubscription.filters.length; i++) | 247 for (let i = 0; i < customSubscription.filters.length; i++) |
248 { | 248 { |
249 if (customSubscription.filters[i].text == filter.text) | 249 if (customSubscription.filters[i].text == filter.text) |
250 { | 250 { |
251 customSubscription.filters.splice(i, 1); | 251 customSubscription.filters.splice(i, 1); |
252 modules.filterNotifier.FilterNotifier.emit("filter.removed", | 252 modules.filterNotifier.FilterNotifier.emit("filter.removed", |
253 filter); | 253 filter); |
254 return; | 254 return; |
255 } | 255 } |
256 } | 256 } |
257 } | 257 } |
258 } | 258 } |
259 }; | 259 }; |
260 | 260 |
261 /* eslint-disable object-shorthand */ | 261 function Filter(text) |
262 { | |
263 this.text = text; | |
264 this.disabled = false; | |
265 } | |
266 Filter.fromText = (text) => new Filter(text); | |
267 | |
268 function BlockingFilter() | |
269 { | |
270 } | |
271 | |
272 function RegExpFilter() | |
273 { | |
274 } | |
275 RegExpFilter.typeMap = Object.create(null); | |
276 | |
262 modules.filterClasses = { | 277 modules.filterClasses = { |
263 BlockingFilter: () => {}, | 278 BlockingFilter, |
264 Filter: function(text) | 279 Filter, |
265 { | 280 RegExpFilter |
266 this.text = text; | 281 }; |
267 this.disabled = false; | |
268 }, | |
269 RegExpFilter: () => {} | |
270 }; | |
271 /* eslint-enable object-shorthand */ | |
272 modules.filterClasses.Filter.fromText = function(text) | |
273 { | |
274 return new modules.filterClasses.Filter(text); | |
275 }; | |
276 modules.filterClasses.RegExpFilter.typeMap = Object.create(null); | |
277 | 282 |
278 modules.filterValidation = | 283 modules.filterValidation = |
279 { | 284 { |
280 parseFilter(text) | 285 parseFilter(text) |
281 { | 286 { |
282 if (params.filterError) | 287 if (params.filterError) |
283 return {error: "Invalid filter"}; | 288 return {error: "Invalid filter"}; |
284 return {filter: modules.filterClasses.Filter.fromText(text)}; | 289 return {filter: modules.filterClasses.Filter.fromText(text)}; |
285 }, | 290 }, |
286 parseFilters(text) | 291 parseFilters(text) |
287 { | 292 { |
288 if (params.filterError) | 293 if (params.filterError) |
289 return {errors: ["Invalid filter"]}; | 294 return {errors: ["Invalid filter"]}; |
290 return { | 295 return { |
291 filters: text.split("\n") | 296 filters: text.split("\n") |
292 .filter(filter => !!filter) | 297 .filter((filter) => !!filter) |
293 .map(modules.filterClasses.Filter.fromText), | 298 .map(modules.filterClasses.Filter.fromText), |
294 errors: [] | 299 errors: [] |
295 }; | 300 }; |
296 } | 301 } |
297 }; | 302 }; |
298 | 303 |
299 modules.synchronizer = { | 304 modules.synchronizer = { |
300 Synchronizer: { | 305 Synchronizer: { |
301 _downloading: false, | 306 _downloading: false, |
302 execute(subscription, manual) | 307 execute(subscription, manual) |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 updateFromURL(modules.info); | 354 updateFromURL(modules.info); |
350 | 355 |
351 modules.subscriptionInit = { | 356 modules.subscriptionInit = { |
352 reinitialized: params.filterlistsReinitialized | 357 reinitialized: params.filterlistsReinitialized |
353 }; | 358 }; |
354 | 359 |
355 modules.messaging = { | 360 modules.messaging = { |
356 port: new EventEmitter() | 361 port: new EventEmitter() |
357 }; | 362 }; |
358 | 363 |
359 window.addEventListener("message", event => | 364 window.addEventListener("message", (event) => |
360 { | 365 { |
361 if (event.data.type != "message") | 366 if (event.data.type != "message") |
362 return; | 367 return; |
363 let message = event.data.payload; | 368 let message = event.data.payload; |
364 let {messageId} = event.data; | 369 let {messageId} = event.data; |
365 let sender = { | 370 let sender = { |
366 page: new ext.Page(event.source) | 371 page: new ext.Page(event.source) |
367 }; | 372 }; |
368 | 373 |
369 let listeners = modules.messaging.port._listeners[message.type]; | 374 let listeners = modules.messaging.port._listeners[message.type]; |
370 if (!listeners) | 375 if (!listeners) |
371 return; | 376 return; |
372 | 377 |
373 function reply(responseMessage) | 378 function reply(responseMessage) |
374 { | 379 { |
375 event.source.postMessage({ | 380 event.source.postMessage({ |
376 type: "response", | 381 type: "response", |
377 messageId, | 382 messageId, |
378 payload: responseMessage | 383 payload: responseMessage |
379 }, "*"); | 384 }, "*"); |
380 } | 385 } |
381 | 386 |
382 for (let listener of listeners) | 387 for (let listener of listeners) |
383 { | 388 { |
384 let response = listener(message, sender); | 389 let response = listener(message, sender); |
385 if (response && typeof response.then == "function") | 390 if (response && typeof response.then == "function") |
386 { | 391 { |
387 response.then( | 392 response.then( |
388 reply, | 393 reply, |
389 reason => | 394 (reason) => |
390 { | 395 { |
391 console.error(reason); | 396 console.error(reason); |
392 reply(undefined); | 397 reply(undefined); |
393 } | 398 } |
394 ); | 399 ); |
395 } | 400 } |
396 else if (typeof response != "undefined") | 401 else if (typeof response != "undefined") |
402 { | |
397 reply(response); | 403 reply(response); |
404 } | |
398 } | 405 } |
399 }); | 406 }); |
400 | 407 |
401 window.Services = { | 408 window.Services = { |
402 vc: { | 409 vc: { |
403 compare(v1, v2) | 410 compare(v1, v2) |
404 { | 411 { |
405 return parseFloat(v1) - parseFloat(v2); | 412 return parseFloat(v1) - parseFloat(v2); |
406 } | 413 } |
407 } | 414 } |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 payload: { | 463 payload: { |
457 title: "Custom subscription", | 464 title: "Custom subscription", |
458 url: "http://example.com/custom.txt", | 465 url: "http://example.com/custom.txt", |
459 confirm: true, | 466 confirm: true, |
460 type: "subscriptions.add" | 467 type: "subscriptions.add" |
461 } | 468 } |
462 }, "*"); | 469 }, "*"); |
463 }, 1000); | 470 }, 1000); |
464 } | 471 } |
465 | 472 |
466 ext.devtools.onCreated.addListener(panel => | 473 ext.devtools.onCreated.addListener((panel) => |
467 { | 474 { |
468 // blocked request | 475 // blocked request |
469 panel.sendMessage({ | 476 panel.sendMessage({ |
470 type: "add-record", | 477 type: "add-record", |
471 request: { | 478 request: { |
472 url: "http://adserver.example.com/ad_banner.png", | 479 url: "http://adserver.example.com/ad_banner.png", |
473 type: "IMAGE", | 480 type: "IMAGE", |
474 docDomain: "example.com" | 481 docDomain: "example.com" |
475 }, | 482 }, |
476 filter: { | 483 filter: { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
532 docDomain: "example.com" | 539 docDomain: "example.com" |
533 }, | 540 }, |
534 filter: { | 541 filter: { |
535 text: "||example.com/some-annoying-popup$popup", | 542 text: "||example.com/some-annoying-popup$popup", |
536 whitelisted: false, | 543 whitelisted: false, |
537 userDefined: true, | 544 userDefined: true, |
538 subscription: null | 545 subscription: null |
539 } | 546 } |
540 }); | 547 }); |
541 }); | 548 }); |
542 } | 549 }()); |
LEFT | RIGHT |