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

Powered by Google App Engine
This is Rietveld