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

Delta Between Two Patch Sets: background.js

Issue 6393086494113792: Issue 154 - Added devtools panel showing blocked and blockable items (Closed)
Left Patch Set: Rebased Created March 3, 2015, 3:16 p.m.
Right Patch Set: Adapt for UI changes generating domain specific filters when necessary Created Feb. 3, 2016, 10:40 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 | chrome/devtools.html » ('j') | 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-2015 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 with(require("filterClasses")) 18 with(require("filterClasses"))
19 { 19 {
20 this.Filter = Filter; 20 this.Filter = Filter;
21 this.BlockingFilter = BlockingFilter; 21 this.BlockingFilter = BlockingFilter;
22 this.WhitelistFilter = WhitelistFilter; 22 this.WhitelistFilter = WhitelistFilter;
23 this.RegExpFilter = RegExpFilter;
23 } 24 }
24 with(require("subscriptionClasses")) 25 with(require("subscriptionClasses"))
25 { 26 {
26 this.Subscription = Subscription; 27 this.Subscription = Subscription;
27 this.DownloadableSubscription = DownloadableSubscription; 28 this.DownloadableSubscription = DownloadableSubscription;
28 this.SpecialSubscription = SpecialSubscription; 29 this.SpecialSubscription = SpecialSubscription;
29 } 30 }
30 with(require("whitelisting")) 31 with(require("whitelisting"))
31 { 32 {
32 this.isPageWhitelisted = isPageWhitelisted; 33 this.checkWhitelisted = checkWhitelisted;
33 this.isFrameWhitelisted = isFrameWhitelisted;
34 this.processKey = processKey; 34 this.processKey = processKey;
35 this.getKey = getKey; 35 this.getKey = getKey;
36 } 36 }
37 with(require("url")) 37 with(require("url"))
38 { 38 {
39 this.stringifyURL = stringifyURL; 39 this.stringifyURL = stringifyURL;
40 this.isThirdParty = isThirdParty; 40 this.isThirdParty = isThirdParty;
41 this.extractHostFromFrame = extractHostFromFrame; 41 this.extractHostFromFrame = extractHostFromFrame;
42 } 42 }
43 with(require("icon"))
44 {
45 this.updateIcon = updateIcon;
46 this.startIconAnimation = startIconAnimation;
47 this.stopIconAnimation = stopIconAnimation;
48 }
49 with(require("devtools"))
50 {
51 this.hasDevToolsPanel = hasDevToolsPanel;
52 this.logHiddenElements = logHiddenElements;
53 }
54 var FilterStorage = require("filterStorage").FilterStorage; 43 var FilterStorage = require("filterStorage").FilterStorage;
44 var FilterNotifier = require("filterNotifier").FilterNotifier;
55 var ElemHide = require("elemHide").ElemHide; 45 var ElemHide = require("elemHide").ElemHide;
56 var defaultMatcher = require("matcher").defaultMatcher; 46 var defaultMatcher = require("matcher").defaultMatcher;
57 var Prefs = require("prefs").Prefs; 47 var Prefs = require("prefs").Prefs;
58 var Synchronizer = require("synchronizer").Synchronizer; 48 var Synchronizer = require("synchronizer").Synchronizer;
59 var Utils = require("utils").Utils; 49 var Utils = require("utils").Utils;
60 var NotificationStorage = require("notification").Notification;
61 var initAntiAdblockNotification = require("antiadblockInit").initAntiAdblockNoti fication;
62 var parseFilters = require("filterValidation").parseFilters; 50 var parseFilters = require("filterValidation").parseFilters;
63 var composeFilters = require("filterComposer").composeFilters; 51 var composeFilters = require("filterComposer").composeFilters;
64 52 var updateIcon = require("icon").updateIcon;
65 // Chrome on Linux does not fully support chrome.notifications until version 35 53 var initNotifications = require("notificationHelper").initNotifications;
66 // https://code.google.com/p/chromium/issues/detail?id=291485 54 var showNextNotificationForUrl = require("notificationHelper").showNextNotificat ionForUrl;
67 var canUseChromeNotifications = require("info").platform == "chromium" 55 var devtools = require("devtools");
68 && "notifications" in chrome
69 && (navigator.platform.indexOf("Linux") == -1 || parseInt(require("info").appl icationVersion, 10) > 34);
70 56
71 var seenDataCorruption = false; 57 var seenDataCorruption = false;
72 var filterlistsReinitialized = false; 58 var filterlistsReinitialized = false;
73 require("filterNotifier").FilterNotifier.addListener(function(action) 59
74 { 60 function init()
75 if (action == "load") 61 {
76 { 62 var filtersLoaded = new Promise(function(resolve)
77 var addonVersion = require("info").addonVersion; 63 {
78 var prevVersion = ext.storage.currentVersion; 64 function onFilterAction(action)
65 {
66 if (action == "load")
67 {
68 FilterNotifier.removeListener(onFilterAction);
69 resolve();
70 }
71 }
72 FilterNotifier.addListener(onFilterAction);
73 });
74
75 function onLoaded()
76 {
77 var info = require("info");
78 var previousVersion = Prefs.currentVersion;
79 79
80 // There are no filters stored so we need to reinitialize all filterlists 80 // There are no filters stored so we need to reinitialize all filterlists
81 if (!FilterStorage.firstRun && FilterStorage.subscriptions.length === 0) 81 if (!FilterStorage.firstRun && FilterStorage.subscriptions.length === 0)
82 { 82 {
83 filterlistsReinitialized = true; 83 filterlistsReinitialized = true;
84 prevVersion = null; 84 previousVersion = null;
85 } 85 }
86 86
87 if (prevVersion != addonVersion || FilterStorage.firstRun) 87 if (previousVersion != info.addonVersion || FilterStorage.firstRun)
88 { 88 {
89 seenDataCorruption = prevVersion && FilterStorage.firstRun; 89 seenDataCorruption = previousVersion && FilterStorage.firstRun;
90 ext.storage.currentVersion = addonVersion; 90 Prefs.currentVersion = info.addonVersion;
91 addSubscription(prevVersion); 91 addSubscription(previousVersion);
92 } 92 }
93 93
94 if (canUseChromeNotifications) 94 initNotifications();
95 initChromeNotifications(); 95
96 initAntiAdblockNotification(); 96 // Update browser actions and context menus when whitelisting might have
97 97 // changed. That is now when initally loading the filters and later when
98 // The "Hide placeholders" option has been removed from the UI in 1.8.8.1285 98 // importing backups or saving filter changes.
99 // So we reset the option for users updating from older versions. 99 FilterNotifier.addListener(function(action)
100 if (prevVersion && Services.vc.compare(prevVersion, "1.8.8.1285") < 0) 100 {
101 Prefs.hidePlaceholders = true; 101 if (action == "load" || action == "save")
102 } 102 refreshIconAndContextMenuForAllPages();
103 103 });
104 // update browser actions when whitelisting might have changed,
105 // due to loading filters or saving filter changes
106 if (action == "load" || action == "save")
107 refreshIconAndContextMenuForAllPages(); 104 refreshIconAndContextMenuForAllPages();
108 }); 105 }
106
107 Promise.all([filtersLoaded, Prefs.isLoaded]).then(onLoaded);
108 }
109 init();
109 110
110 // Special-case domains for which we cannot use style-based hiding rules. 111 // Special-case domains for which we cannot use style-based hiding rules.
111 // See http://crbug.com/68705. 112 // See http://crbug.com/68705.
112 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"]; 113 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"];
113 114
114 var htmlPages = new ext.PageMap(); 115 var htmlPages = new ext.PageMap();
115
116 function removeDeprecatedOptions()
117 {
118 var deprecatedOptions = ["specialCaseYouTube", "experimental", "disableInlineT extAds"];
119 deprecatedOptions.forEach(function(option)
120 {
121 if (option in ext.storage)
122 delete ext.storage[option];
123 });
124 }
125
126 // Remove deprecated options before we do anything else.
127 removeDeprecatedOptions();
128
129 var activeNotification = null;
130 116
131 var contextMenuItem = { 117 var contextMenuItem = {
132 title: ext.i18n.getMessage("block_element"), 118 title: ext.i18n.getMessage("block_element"),
133 contexts: ["image", "video", "audio"], 119 contexts: ["image", "video", "audio"],
134 onclick: function(page) 120 onclick: function(page)
135 { 121 {
136 page.sendMessage({type: "clickhide-new-filter"}); 122 page.sendMessage({type: "clickhide-new-filter"});
137 } 123 }
138 }; 124 };
139 125
140 // Adds or removes browser action icon according to options. 126 // Adds or removes browser action icon according to options.
141 function refreshIconAndContextMenu(page) 127 function refreshIconAndContextMenu(page)
142 { 128 {
143 var whitelisted = isPageWhitelisted(page); 129 var whitelisted = !!checkWhitelisted(page);
144 updateIcon(page, whitelisted); 130 updateIcon(page, whitelisted);
145 131
146 // show or hide the context menu entry dependent on whether 132 // show or hide the context menu entry dependent on whether
147 // adblocking is active on that page 133 // adblocking is active on that page
148 page.contextMenus.removeAll(); 134 page.contextMenus.remove(contextMenuItem);
149 if (Prefs.shouldShowBlockElementMenu && !whitelisted && htmlPages.has(page)) 135 if (Prefs.shouldShowBlockElementMenu && !whitelisted && htmlPages.has(page))
150 page.contextMenus.create(contextMenuItem); 136 page.contextMenus.create(contextMenuItem);
151 } 137 }
152 138
153 function refreshIconAndContextMenuForAllPages() 139 function refreshIconAndContextMenuForAllPages()
154 { 140 {
155 ext.pages.query({}, function(pages) 141 ext.pages.query({}, function(pages)
156 { 142 {
157 pages.forEach(refreshIconAndContextMenu); 143 pages.forEach(refreshIconAndContextMenu);
158 }); 144 });
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 subscription.disabled = true; 206 subscription.disabled = true;
221 FilterStorage.addSubscription(subscription); 207 FilterStorage.addSubscription(subscription);
222 if (subscription instanceof DownloadableSubscription && !subscription.last Download) 208 if (subscription instanceof DownloadableSubscription && !subscription.last Download)
223 Synchronizer.execute(subscription); 209 Synchronizer.execute(subscription);
224 } 210 }
225 } 211 }
226 212
227 if (!addSubscription && !addAcceptable) 213 if (!addSubscription && !addAcceptable)
228 return; 214 return;
229 215
230 function notifyUser() 216 Promise.resolve(addSubscription && fetch("subscriptions.xml")
231 { 217 .then(function(response)
232 ext.pages.open(ext.getURL("firstRun.html")); 218 {
233 } 219 return response.text();
234 220 })
235 if (addSubscription) 221 .then(function(text)
236 { 222 {
237 // Load subscriptions data 223 var doc = new DOMParser().parseFromString(text, "application/xml");
238 var request = new XMLHttpRequest(); 224 var nodes = doc.getElementsByTagName("subscription");
239 request.open("GET", "subscriptions.xml"); 225 var node = Utils.chooseFilterSubscription(nodes);
240 request.addEventListener("load", function() 226 var subscription = node && Subscription.fromURL(node.getAttribute("url"));
241 { 227
242 var node = Utils.chooseFilterSubscription(request.responseXML.getElementsB yTagName("subscription"));
243 var subscription = (node ? Subscription.fromURL(node.getAttribute("url")) : null);
244 if (subscription) 228 if (subscription)
245 { 229 {
246 FilterStorage.addSubscription(subscription); 230 FilterStorage.addSubscription(subscription);
231
247 subscription.disabled = false; 232 subscription.disabled = false;
248 subscription.title = node.getAttribute("title"); 233 subscription.title = node.getAttribute("title");
249 subscription.homepage = node.getAttribute("homepage"); 234 subscription.homepage = node.getAttribute("homepage");
250 if (subscription instanceof DownloadableSubscription && !subscription.la stDownload) 235
236 if (subscription instanceof DownloadableSubscription &&
237 !subscription.lastDownload)
251 Synchronizer.execute(subscription); 238 Synchronizer.execute(subscription);
252 239 }
253 notifyUser(); 240 })
254 } 241 )
255 }, false); 242 .then(function()
256 request.send(null); 243 {
257 } 244 if (!Prefs.suppress_first_run_page)
258 else 245 ext.pages.open(ext.getURL("firstRun.html"));
259 notifyUser(); 246 });
260 } 247 }
261 248
262 Prefs.addListener(function(name) 249 Prefs.onChanged.addListener(function(name)
263 { 250 {
264 if (name == "shouldShowBlockElementMenu") 251 if (name == "shouldShowBlockElementMenu")
265 refreshIconAndContextMenuForAllPages(); 252 refreshIconAndContextMenuForAllPages();
266 }); 253 });
267
268 function prepareNotificationIconAndPopup()
269 {
270 var animateIcon = (activeNotification.type !== "question");
271 activeNotification.onClicked = function()
272 {
273 if (animateIcon)
274 stopIconAnimation();
275 notificationClosed();
276 };
277 if (animateIcon)
278 startIconAnimation(activeNotification.type);
279 }
280
281 function openNotificationLinks()
282 {
283 if (activeNotification.links)
284 {
285 activeNotification.links.forEach(function(link)
286 {
287 ext.windows.getLastFocused(function(win)
288 {
289 win.openTab(Utils.getDocLink(link));
290 });
291 });
292 }
293 }
294
295 function notificationButtonClick(buttonIndex)
296 {
297 if (activeNotification.type === "question")
298 {
299 NotificationStorage.triggerQuestionListeners(activeNotification.id, buttonIn dex === 0);
300 NotificationStorage.markAsShown(activeNotification.id);
301 activeNotification.onClicked();
302 }
303 else if (activeNotification.links && activeNotification.links[buttonIndex])
304 {
305 ext.windows.getLastFocused(function(win)
306 {
307 win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex]));
308 });
309 }
310 }
311
312 function notificationClosed()
313 {
314 activeNotification = null;
315 }
316
317 function imgToBase64(url, callback)
318 {
319 var canvas = document.createElement("canvas"),
320 ctx = canvas.getContext("2d"),
321 img = new Image;
322 img.src = url;
323 img.onload = function()
324 {
325 canvas.height = img.height;
326 canvas.width = img.width;
327 ctx.drawImage(img, 0, 0);
328 callback(canvas.toDataURL("image/png"));
329 canvas = null;
330 };
331 }
332
333 function initChromeNotifications()
334 {
335 // Chrome hides notifications in notification center when clicked so we need t o clear them
336 function clearActiveNotification(notificationId)
337 {
338 if (activeNotification && activeNotification.type != "question" && !("links" in activeNotification))
339 return;
340
341 chrome.notifications.clear(notificationId, function(wasCleared)
342 {
343 if (wasCleared)
344 notificationClosed();
345 });
346 }
347
348 chrome.notifications.onButtonClicked.addListener(function(notificationId, butt onIndex)
349 {
350 notificationButtonClick(buttonIndex);
351 clearActiveNotification(notificationId);
352 });
353 chrome.notifications.onClicked.addListener(clearActiveNotification);
354 chrome.notifications.onClosed.addListener(notificationClosed);
355 }
356
357 function showNotification(notification)
358 {
359 if (activeNotification && activeNotification.id === notification.id)
360 return;
361
362 activeNotification = notification;
363 if (activeNotification.type === "critical" || activeNotification.type === "que stion")
364 {
365 var texts = NotificationStorage.getLocalizedTexts(notification);
366 var title = texts.title || "";
367 var message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") : "";
368 var iconUrl = ext.getURL("icons/detailed/abp-128.png");
369 var hasLinks = activeNotification.links && activeNotification.links.length > 0;
370
371 if (canUseChromeNotifications)
372 {
373 var opts = {
374 type: "basic",
375 title: title,
376 message: message,
377 buttons: [],
378 priority: 2 // We use the highest priority to prevent the notification f rom closing automatically
379 };
380 if (activeNotification.type === "question")
381 {
382 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_yes")});
383 opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt on_no")});
384 }
385 else
386 {
387 var regex = /<a>(.*?)<\/a>/g;
388 var plainMessage = texts.message || "";
389 var match;
390 while (match = regex.exec(plainMessage))
391 opts.buttons.push({title: match[1]});
392 }
393
394 imgToBase64(iconUrl, function(iconData)
395 {
396 opts["iconUrl"] = iconData;
397 chrome.notifications.create("", opts, function() {});
398 });
399 }
400 else if ("Notification" in window && activeNotification.type !== "question")
401 {
402 if (hasLinks)
403 message += " " + ext.i18n.getMessage("notification_without_buttons");
404
405 imgToBase64(iconUrl, function(iconData)
406 {
407 var notification = new Notification(
408 title,
409 {
410 lang: Utils.appLocale,
411 dir: ext.i18n.getMessage("@@bidi_dir"),
412 body: message,
413 icon: iconData
414 }
415 );
416
417 notification.addEventListener("click", openNotificationLinks);
418 notification.addEventListener("close", notificationClosed);
419 });
420 }
421 else
422 {
423 var message = title + "\n" + message;
424 if (hasLinks)
425 message += "\n\n" + ext.i18n.getMessage("notification_with_buttons");
426
427 var approved = confirm(message);
428 if (activeNotification.type === "question")
429 notificationButtonClick(approved ? 0 : 1);
430 else if (approved)
431 openNotificationLinks();
432 }
433 }
434 prepareNotificationIconAndPopup();
435 }
436 254
437 // This is a hack to speedup loading of the options page on Safari. 255 // This is a hack to speedup loading of the options page on Safari.
438 // Once we replaced the background page proxy with message passing 256 // Once we replaced the background page proxy with message passing
439 // this global function should removed. 257 // this global function should removed.
440 function getUserFilters() 258 function getUserFilters()
441 { 259 {
442 var filters = []; 260 var filters = [];
443 var exceptions = []; 261 var exceptions = [];
444 262
445 for (var i = 0; i < FilterStorage.subscriptions.length; i++) 263 for (var i = 0; i < FilterStorage.subscriptions.length; i++)
(...skipping 14 matching lines...) Expand all
460 278
461 return {filters: filters, exceptions: exceptions}; 279 return {filters: filters, exceptions: exceptions};
462 } 280 }
463 281
464 ext.onMessage.addListener(function (msg, sender, sendResponse) 282 ext.onMessage.addListener(function (msg, sender, sendResponse)
465 { 283 {
466 switch (msg.type) 284 switch (msg.type)
467 { 285 {
468 case "get-selectors": 286 case "get-selectors":
469 var selectors = []; 287 var selectors = [];
470 288 var trace = devtools && devtools.hasPanel(sender.page);
471 if (!isFrameWhitelisted(sender.page, sender.frame, "DOCUMENT") && 289
472 !isFrameWhitelisted(sender.page, sender.frame, "ELEMHIDE")) 290 if (!checkWhitelisted(sender.page, sender.frame,
291 RegExpFilter.typeMap.DOCUMENT |
292 RegExpFilter.typeMap.ELEMHIDE))
473 { 293 {
474 var noStyleRules = false; 294 var noStyleRules = false;
295 var specificOnly = checkWhitelisted(sender.page, sender.frame,
296 RegExpFilter.typeMap.GENERICHIDE);
475 var host = extractHostFromFrame(sender.frame); 297 var host = extractHostFromFrame(sender.frame);
298
476 for (var i = 0; i < noStyleRulesHosts.length; i++) 299 for (var i = 0; i < noStyleRulesHosts.length; i++)
477 { 300 {
478 var noStyleHost = noStyleRulesHosts[i]; 301 var noStyleHost = noStyleRulesHosts[i];
479 if (host == noStyleHost || (host.length > noStyleHost.length && 302 if (host == noStyleHost || (host.length > noStyleHost.length &&
480 host.substr(host.length - noStyleHost.leng th - 1) == "." + noStyleHost)) 303 host.substr(host.length - noStyleHost.leng th - 1) == "." + noStyleHost))
481 { 304 {
482 noStyleRules = true; 305 noStyleRules = true;
483 } 306 }
484 } 307 }
485 selectors = ElemHide.getSelectorsForDomain(host, false); 308 selectors = ElemHide.getSelectorsForDomain(host, specificOnly);
486 if (noStyleRules) 309 if (noStyleRules)
487 { 310 {
488 selectors = selectors.filter(function(s) 311 selectors = selectors.filter(function(s)
489 { 312 {
490 return !/\[style[\^\$]?=/.test(s); 313 return !/\[style[\^\$]?=/.test(s);
491 }); 314 });
492 } 315 }
493 } 316 }
494 317
495 sendResponse({selectors: selectors, trace: hasDevToolsPanel(sender.page)}) ; 318 sendResponse({selectors: selectors, trace: trace});
496 break; 319 break;
497 case "should-collapse": 320 case "should-collapse":
498 if (isFrameWhitelisted(sender.page, sender.frame, "DOCUMENT")) 321 if (checkWhitelisted(sender.page, sender.frame))
499 { 322 {
500 sendResponse(false); 323 sendResponse(false);
501 break; 324 break;
502 } 325 }
503 326
504 var url = new URL(msg.url); 327 var typeMask = RegExpFilter.typeMap[msg.mediatype];
505 var documentHost = extractHostFromFrame(sender.frame); 328 var documentHost = extractHostFromFrame(sender.frame);
506 var filter = defaultMatcher.matchesAny( 329 var sitekey = getKey(sender.page, sender.frame);
507 stringifyURL(url), msg.mediatype, 330 var blocked = false;
508 documentHost, isThirdParty(url, documentHost) 331
509 ); 332 for (var i = 0; i < msg.urls.length; i++)
510 333 {
511 if (filter instanceof BlockingFilter) 334 var url = new URL(msg.urls[i], msg.baseURL);
512 { 335 var filter = defaultMatcher.matchesAny(
513 var collapse = filter.collapse; 336 stringifyURL(url), typeMask,
514 if (collapse == null) 337 documentHost, isThirdParty(url, documentHost), sitekey
515 collapse = Prefs.hidePlaceholders; 338 );
516 sendResponse(collapse); 339
517 } 340 if (filter instanceof BlockingFilter)
518 else 341 {
519 sendResponse(false); 342 if (filter.collapse != null)
343 {
344 sendResponse(filter.collapse);
345 return;
346 }
347
348 blocked = true;
349 }
350 }
351
352 sendResponse(blocked && Prefs.hidePlaceholders);
520 break; 353 break;
521 case "get-domain-enabled-state": 354 case "get-domain-enabled-state":
522 // Returns whether this domain is in the exclusion list. 355 // Returns whether this domain is in the exclusion list.
523 // The browser action popup asks us this. 356 // The browser action popup asks us this.
524 if(sender.page) 357 if(sender.page)
525 { 358 {
526 sendResponse({enabled: !isPageWhitelisted(sender.page)}); 359 sendResponse({enabled: !checkWhitelisted(sender.page)});
527 return; 360 return;
528 } 361 }
529 break; 362 break;
530 case "add-filters": 363 case "add-filters":
531 var filters; 364 var result = parseFilters(msg.text);
532 try 365
533 { 366 if (result.errors.length > 0)
534 filters = parseFilters(msg.text); 367 {
535 } 368 sendResponse({status: "invalid", error: result.errors.join("\n")});
536 catch (error)
537 {
538 sendResponse({status: "invalid", error: error});
539 break; 369 break;
540 } 370 }
541 371
542 for (var i = 0; i < filters.length; i++) 372 for (var i = 0; i < result.filters.length; i++)
543 FilterStorage.addFilter(filters[i]); 373 FilterStorage.addFilter(result.filters[i]);
544 374
545 sendResponse({status: "ok"}); 375 sendResponse({status: "ok"});
546 break;
547 case "add-subscription":
548 ext.showOptions(function(page)
549 {
550 page.sendMessage(msg);
551 });
552 break; 376 break;
553 case "add-sitekey": 377 case "add-sitekey":
554 processKey(msg.token, sender.page, sender.frame); 378 processKey(msg.token, sender.page, sender.frame);
555 break; 379 break;
556 case "report-html-page": 380 case "report-html-page":
557 htmlPages.set(sender.page, null); 381 htmlPages.set(sender.page, null);
558 refreshIconAndContextMenu(sender.page); 382 refreshIconAndContextMenu(sender.page);
559 break; 383 break;
560 case "compose-filters": 384 case "compose-filters":
561 sendResponse(composeFilters( 385 sendResponse(composeFilters({
562 msg.tagName, msg.id, msg.src, msg.style, 386 tagName: msg.tagName,
563 msg.classes, msg.urls, new URL(msg.baseURL) 387 id: msg.id,
564 )); 388 src: msg.src,
389 style: msg.style,
390 classes: msg.classes,
391 urls: msg.urls,
392 type: msg.mediatype,
393 baseURL: msg.baseURL,
394 page: sender.page,
395 frame: sender.frame
396 }));
397 break;
565 case "trace-elemhide": 398 case "trace-elemhide":
566 logHiddenElements(sender.page, msg.selectors, extractHostFromFrame(sender. frame)); 399 devtools.logHiddenElements(
400 sender.page, msg.selectors,
401 extractHostFromFrame(sender.frame)
402 );
567 break; 403 break;
568 case "forward": 404 case "forward":
569 if (sender.page) 405 if (sender.page)
570 { 406 {
571 if (msg.expectsResponse) 407 if (msg.expectsResponse)
572 { 408 {
573 sender.page.sendMessage(msg.payload, sendResponse); 409 sender.page.sendMessage(msg.payload, sendResponse);
574 return true; 410 return true;
575 } 411 }
576 412
577 sender.page.sendMessage(msg.payload); 413 sender.page.sendMessage(msg.payload);
578 } 414 }
579 break; 415 break;
580 } 416 }
581 }); 417 });
582 418
583 // update icon when page changes location 419 // update icon when page changes location
584 ext.pages.onLoading.addListener(function(page) 420 ext.pages.onLoading.addListener(function(page)
585 { 421 {
586 page.sendMessage({type: "clickhide-deactivate"}); 422 page.sendMessage({type: "clickhide-deactivate"});
587 refreshIconAndContextMenu(page); 423 refreshIconAndContextMenu(page);
424 showNextNotificationForUrl(page.url);
588 }); 425 });
589
590 setTimeout(function()
591 {
592 var notificationToShow = NotificationStorage.getNextToShow();
593 if (notificationToShow)
594 showNotification(notificationToShow);
595 }, 3 * 60 * 1000);
LEFTRIGHT

Powered by Google App Engine
This is Rietveld