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

Powered by Google App Engine
This is Rietveld