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

Powered by Google App Engine
This is Rietveld