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

Delta Between Two Patch Sets: background.js

Issue 5225119261655040: Issue 1282 - Don't generate filters conflicting with existing exception rules (Closed)
Left Patch Set: Created Dec. 15, 2014, 2:47 p.m.
Right Patch Set: Addressed comment Created March 3, 2015, 2:59 p.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 | include.postload.js » ('j') | lib/filterComposer.js » ('J')
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-2015 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;
24 } 23 }
25 with(require("subscriptionClasses")) 24 with(require("subscriptionClasses"))
26 { 25 {
27 this.Subscription = Subscription; 26 this.Subscription = Subscription;
28 this.DownloadableSubscription = DownloadableSubscription; 27 this.DownloadableSubscription = DownloadableSubscription;
29 this.SpecialSubscription = SpecialSubscription; 28 this.SpecialSubscription = SpecialSubscription;
30 } 29 }
31 with(require("whitelisting")) 30 with(require("whitelisting"))
32 { 31 {
33 this.isWhitelisted = isWhitelisted; 32 this.isPageWhitelisted = isPageWhitelisted;
34 this.isFrameWhitelisted = isFrameWhitelisted; 33 this.isFrameWhitelisted = isFrameWhitelisted;
35 this.processKey = processKey; 34 this.processKey = processKey;
36 this.getKey = getKey; 35 this.getKey = getKey;
36 }
37 with(require("url"))
38 {
39 this.stringifyURL = stringifyURL;
40 this.isThirdParty = isThirdParty;
41 this.extractHostFromFrame = extractHostFromFrame;
42 }
43 with(require("icon"))
44 {
45 this.updateIcon = updateIcon;
46 this.startIconAnimation = startIconAnimation;
47 this.stopIconAnimation = stopIconAnimation;
37 } 48 }
38 var FilterStorage = require("filterStorage").FilterStorage; 49 var FilterStorage = require("filterStorage").FilterStorage;
39 var ElemHide = require("elemHide").ElemHide; 50 var ElemHide = require("elemHide").ElemHide;
40 var defaultMatcher = require("matcher").defaultMatcher; 51 var defaultMatcher = require("matcher").defaultMatcher;
41 var Prefs = require("prefs").Prefs; 52 var Prefs = require("prefs").Prefs;
42 var Synchronizer = require("synchronizer").Synchronizer; 53 var Synchronizer = require("synchronizer").Synchronizer;
43 var Utils = require("utils").Utils; 54 var Utils = require("utils").Utils;
44 var Notification = require("notification").Notification; 55 var NotificationStorage = require("notification").Notification;
45 var initAntiAdblockNotification = require("antiadblockInit").initAntiAdblockNoti fication; 56 var initAntiAdblockNotification = require("antiadblockInit").initAntiAdblockNoti fication;
46 var parseFilters = require("filterValidation").parseFilters; 57 var parseFilters = require("filterValidation").parseFilters;
47 58 var composeFilters = require("filterComposer").composeFilters;
48 // Some types cannot be distinguished
49 RegExpFilter.typeMap.OBJECT_SUBREQUEST = RegExpFilter.typeMap.OBJECT;
50 RegExpFilter.typeMap.MEDIA = RegExpFilter.typeMap.FONT = RegExpFilter.typeMap.OT HER;
51 59
52 // Chrome on Linux does not fully support chrome.notifications until version 35 60 // Chrome on Linux does not fully support chrome.notifications until version 35
53 // https://code.google.com/p/chromium/issues/detail?id=291485 61 // https://code.google.com/p/chromium/issues/detail?id=291485
54 var canUseChromeNotifications = require("info").platform == "chromium" 62 var canUseChromeNotifications = require("info").platform == "chromium"
55 && "notifications" in chrome 63 && "notifications" in chrome
56 && (navigator.platform.indexOf("Linux") == -1 || parseInt(require("info").appl icationVersion, 10) > 34); 64 && (navigator.platform.indexOf("Linux") == -1 || parseInt(require("info").appl icationVersion, 10) > 34);
57 65
58 var seenDataCorruption = false; 66 var seenDataCorruption = false;
59 var filterlistsReinitialized = false; 67 var filterlistsReinitialized = false;
60 require("filterNotifier").FilterNotifier.addListener(function(action) 68 require("filterNotifier").FilterNotifier.addListener(function(action)
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 contexts: ["image", "video", "audio"], 128 contexts: ["image", "video", "audio"],
121 onclick: function(page) 129 onclick: function(page)
122 { 130 {
123 page.sendMessage({type: "clickhide-new-filter"}); 131 page.sendMessage({type: "clickhide-new-filter"});
124 } 132 }
125 }; 133 };
126 134
127 // Adds or removes browser action icon according to options. 135 // Adds or removes browser action icon according to options.
128 function refreshIconAndContextMenu(page) 136 function refreshIconAndContextMenu(page)
129 { 137 {
130 var whitelisted = isWhitelisted(page.url); 138 var whitelisted = isPageWhitelisted(page);
131 139 updateIcon(page, whitelisted);
132 var iconFilename;
133 if (whitelisted && require("info").platform != "safari")
134 // There is no grayscale version of the icon for whitelisted pages
135 // when using Safari, because icons are grayscale already and icons
136 // aren't per page in Safari.
137 iconFilename = "icons/abp-$size-whitelisted.png";
138 else
139 iconFilename = "icons/abp-$size.png";
140
141 page.browserAction.setIcon(iconFilename);
142 iconAnimation.registerPage(page, iconFilename);
143 140
144 // show or hide the context menu entry dependent on whether 141 // show or hide the context menu entry dependent on whether
145 // adblocking is active on that page 142 // adblocking is active on that page
146 page.contextMenus.removeAll(); 143 page.contextMenus.removeAll();
147
148 if (Prefs.shouldShowBlockElementMenu && !whitelisted && htmlPages.has(page)) 144 if (Prefs.shouldShowBlockElementMenu && !whitelisted && htmlPages.has(page))
149 page.contextMenus.create(contextMenuItem); 145 page.contextMenus.create(contextMenuItem);
150 } 146 }
151 147
152 function refreshIconAndContextMenuForAllPages() 148 function refreshIconAndContextMenuForAllPages()
153 { 149 {
154 ext.pages.query({}, function(pages) 150 ext.pages.query({}, function(pages)
155 { 151 {
156 pages.forEach(refreshIconAndContextMenu); 152 pages.forEach(refreshIconAndContextMenu);
157 }); 153 });
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 else 253 else
258 notifyUser(); 254 notifyUser();
259 } 255 }
260 256
261 Prefs.addListener(function(name) 257 Prefs.addListener(function(name)
262 { 258 {
263 if (name == "shouldShowBlockElementMenu") 259 if (name == "shouldShowBlockElementMenu")
264 refreshIconAndContextMenuForAllPages(); 260 refreshIconAndContextMenuForAllPages();
265 }); 261 });
266 262
267 // TODO: This hack should be removed, however currently
268 // the firstRun page still calls backgroundPage.openOptions()
269 openOptions = ext.showOptions;
270
271 function prepareNotificationIconAndPopup() 263 function prepareNotificationIconAndPopup()
272 { 264 {
273 var animateIcon = (activeNotification.type !== "question"); 265 var animateIcon = (activeNotification.type !== "question");
274 activeNotification.onClicked = function() 266 activeNotification.onClicked = function()
275 { 267 {
276 if (animateIcon) 268 if (animateIcon)
277 iconAnimation.stop(); 269 stopIconAnimation();
278 notificationClosed(); 270 notificationClosed();
279 }; 271 };
280 if (animateIcon) 272 if (animateIcon)
281 iconAnimation.update(activeNotification.type); 273 startIconAnimation(activeNotification.type);
282 } 274 }
283 275
284 function openNotificationLinks() 276 function openNotificationLinks()
285 { 277 {
286 if (activeNotification.links) 278 if (activeNotification.links)
287 { 279 {
288 activeNotification.links.forEach(function(link) 280 activeNotification.links.forEach(function(link)
289 { 281 {
290 ext.windows.getLastFocused(function(win) 282 ext.windows.getLastFocused(function(win)
291 { 283 {
292 win.openTab(Utils.getDocLink(link)); 284 win.openTab(Utils.getDocLink(link));
293 }); 285 });
294 }); 286 });
295 } 287 }
296 } 288 }
297 289
298 function notificationButtonClick(buttonIndex) 290 function notificationButtonClick(buttonIndex)
299 { 291 {
300 if (activeNotification.type === "question") 292 if (activeNotification.type === "question")
301 { 293 {
302 Notification.triggerQuestionListeners(activeNotification.id, buttonIndex === 0); 294 NotificationStorage.triggerQuestionListeners(activeNotification.id, buttonIn dex === 0);
303 Notification.markAsShown(activeNotification.id); 295 NotificationStorage.markAsShown(activeNotification.id);
304 activeNotification.onClicked(); 296 activeNotification.onClicked();
305 } 297 }
306 else if (activeNotification.links && activeNotification.links[buttonIndex]) 298 else if (activeNotification.links && activeNotification.links[buttonIndex])
307 { 299 {
308 ext.windows.getLastFocused(function(win) 300 ext.windows.getLastFocused(function(win)
309 { 301 {
310 win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex])); 302 win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex]));
311 }); 303 });
312 } 304 }
313 } 305 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 } 350 }
359 351
360 function showNotification(notification) 352 function showNotification(notification)
361 { 353 {
362 if (activeNotification && activeNotification.id === notification.id) 354 if (activeNotification && activeNotification.id === notification.id)
363 return; 355 return;
364 356
365 activeNotification = notification; 357 activeNotification = notification;
366 if (activeNotification.type === "critical" || activeNotification.type === "que stion") 358 if (activeNotification.type === "critical" || activeNotification.type === "que stion")
367 { 359 {
368 var hasWebkitNotifications = typeof webkitNotifications !== "undefined"; 360 var texts = NotificationStorage.getLocalizedTexts(notification);
369 if (hasWebkitNotifications && "createHTMLNotification" in webkitNotification s)
370 {
371 var notification = webkitNotifications.createHTMLNotification("notificatio n.html");
372 notification.show();
373 prepareNotificationIconAndPopup();
374 return;
375 }
376
377 var texts = Notification.getLocalizedTexts(notification);
378 var title = texts.title || ""; 361 var title = texts.title || "";
379 var message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") : ""; 362 var message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") : "";
380 var iconUrl = ext.getURL("icons/abp-128.png"); 363 var iconUrl = ext.getURL("icons/detailed/abp-128.png");
381 var hasLinks = activeNotification.links && activeNotification.links.length > 0; 364 var hasLinks = activeNotification.links && activeNotification.links.length > 0;
382 365
383 if (canUseChromeNotifications) 366 if (canUseChromeNotifications)
384 { 367 {
385 var opts = { 368 var opts = {
386 type: "basic", 369 type: "basic",
387 title: title, 370 title: title,
388 message: message, 371 message: message,
389 buttons: [], 372 buttons: [],
390 priority: 2 // We use the highest priority to prevent the notification f rom closing automatically 373 priority: 2 // We use the highest priority to prevent the notification f rom closing automatically
(...skipping 11 matching lines...) Expand all
402 while (match = regex.exec(plainMessage)) 385 while (match = regex.exec(plainMessage))
403 opts.buttons.push({title: match[1]}); 386 opts.buttons.push({title: match[1]});
404 } 387 }
405 388
406 imgToBase64(iconUrl, function(iconData) 389 imgToBase64(iconUrl, function(iconData)
407 { 390 {
408 opts["iconUrl"] = iconData; 391 opts["iconUrl"] = iconData;
409 chrome.notifications.create("", opts, function() {}); 392 chrome.notifications.create("", opts, function() {});
410 }); 393 });
411 } 394 }
412 else if (hasWebkitNotifications && "createNotification" in webkitNotificatio ns && activeNotification.type !== "question") 395 else if ("Notification" in window && activeNotification.type !== "question")
413 { 396 {
414 if (hasLinks) 397 if (hasLinks)
415 message += " " + ext.i18n.getMessage("notification_without_buttons"); 398 message += " " + ext.i18n.getMessage("notification_without_buttons");
416 399
417 imgToBase64(iconUrl, function(iconData) 400 imgToBase64(iconUrl, function(iconData)
418 { 401 {
419 var notification = webkitNotifications.createNotification(iconData, titl e, message); 402 var notification = new Notification(
420 notification.show(); 403 title,
421 notification.addEventListener("click", openNotificationLinks, false); 404 {
422 notification.addEventListener("close", notificationClosed, false); 405 lang: Utils.appLocale,
406 dir: ext.i18n.getMessage("@@bidi_dir"),
407 body: message,
408 icon: iconData
409 }
410 );
411
412 notification.addEventListener("click", openNotificationLinks);
413 notification.addEventListener("close", notificationClosed);
423 }); 414 });
424 } 415 }
425 else 416 else
426 { 417 {
427 var message = title + "\n" + message; 418 var message = title + "\n" + message;
428 if (hasLinks) 419 if (hasLinks)
429 message += "\n\n" + ext.i18n.getMessage("notification_with_buttons"); 420 message += "\n\n" + ext.i18n.getMessage("notification_with_buttons");
430 421
431 var approved = confirm(message); 422 var approved = confirm(message);
432 if (activeNotification.type === "question") 423 if (activeNotification.type === "question")
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 489
499 sendResponse(selectors); 490 sendResponse(selectors);
500 break; 491 break;
501 case "should-collapse": 492 case "should-collapse":
502 if (isFrameWhitelisted(sender.page, sender.frame, "DOCUMENT")) 493 if (isFrameWhitelisted(sender.page, sender.frame, "DOCUMENT"))
503 { 494 {
504 sendResponse(false); 495 sendResponse(false);
505 break; 496 break;
506 } 497 }
507 498
508 var requestHost = extractHostFromURL(msg.url); 499 var url = new URL(msg.url);
509 var documentHost = extractHostFromFrame(sender.frame); 500 var documentHost = extractHostFromFrame(sender.frame);
510 var thirdParty = isThirdParty(requestHost, documentHost); 501 var filter = defaultMatcher.matchesAny(
511 var filter = defaultMatcher.matchesAny(msg.url, msg.mediatype, documentHos t, thirdParty); 502 stringifyURL(url), msg.mediatype,
503 documentHost, isThirdParty(url, documentHost)
504 );
505
512 if (filter instanceof BlockingFilter) 506 if (filter instanceof BlockingFilter)
513 { 507 {
514 var collapse = filter.collapse; 508 var collapse = filter.collapse;
515 if (collapse == null) 509 if (collapse == null)
516 collapse = Prefs.hidePlaceholders; 510 collapse = Prefs.hidePlaceholders;
517 sendResponse(collapse); 511 sendResponse(collapse);
518 } 512 }
519 else 513 else
520 sendResponse(false); 514 sendResponse(false);
521 break; 515 break;
522 case "check-whitelisted-urls":
523 var documentHost = extractHostFromFrame(sender.frame);
524 var sitekey = getKey(sender.page, sender.frame);
525
526 var result = Object.create(null);
527 for (var i = 0; i < msg.urls.length; i++)
528 {
529 var requestUrl = msg.urls[i];
530 var requestHost = extractHostFromURL(requestUrl);
531
532 var filter = defaultMatcher.matchesAny(
533 requestUrl, msg.mediatype, documentHost,
534 isThirdParty(requestHost, documentHost),
535 sitekey
536 );
537
538 result[requestUrl] = filter instanceof WhitelistFilter;
539 }
540
541 sendResponse(result);
542 break;
543 case "get-filters-from-selectors":
544 var filters = [];
545 var selectors = [];
546
547 if (!isFrameWhitelisted(sender.page, sender.frame, "ELEMHIDE"))
548 {
549 var documentHost = extractHostFromFrame(sender.frame);
550
551 for (var i = 0; i < msg.selectors.length; i++)
552 {
553 var selector = msg.selectors[i];
554 var filter = documentHost + "##" + selector;
555
556 if (!ElemHide.getException(Filter.fromText(filter), documentHost))
557 {
558 filters.push(filter);
559 selectors.push(selector);
560 }
561 }
562 }
563
564 sendResponse({filters: filters, selectors: selectors});
565 break;
566 case "get-domain-enabled-state": 516 case "get-domain-enabled-state":
567 // Returns whether this domain is in the exclusion list. 517 // Returns whether this domain is in the exclusion list.
568 // The browser action popup asks us this. 518 // The browser action popup asks us this.
569 if(sender.page) 519 if(sender.page)
570 { 520 {
571 sendResponse({enabled: !isWhitelisted(sender.page.url)}); 521 sendResponse({enabled: !isPageWhitelisted(sender.page)});
572 return; 522 return;
573 } 523 }
574 break; 524 break;
575 case "add-filters": 525 case "add-filters":
576 var filters; 526 var filters;
577 try 527 try
578 { 528 {
579 filters = parseFilters(msg.text); 529 filters = parseFilters(msg.text);
580 } 530 }
581 catch (error) 531 catch (error)
(...skipping 13 matching lines...) Expand all
595 page.sendMessage(msg); 545 page.sendMessage(msg);
596 }); 546 });
597 break; 547 break;
598 case "add-sitekey": 548 case "add-sitekey":
599 processKey(msg.token, sender.page, sender.frame); 549 processKey(msg.token, sender.page, sender.frame);
600 break; 550 break;
601 case "report-html-page": 551 case "report-html-page":
602 htmlPages.set(sender.page, null); 552 htmlPages.set(sender.page, null);
603 refreshIconAndContextMenu(sender.page); 553 refreshIconAndContextMenu(sender.page);
604 break; 554 break;
555 case "compose-filters":
556 sendResponse(composeFilters({
557 tagName: msg.tagName,
558 id: msg.id,
559 src: msg.src,
560 style: msg.style,
561 classes: msg.classes,
562 urls: msg.urls,
563 type: msg.mediatype,
564 baseURL: msg.baseURL,
565 page: sender.page,
566 frame: sender.frame
567 }));
568 break;
605 case "forward": 569 case "forward":
606 if (sender.page) 570 if (sender.page)
607 { 571 {
608 sender.page.sendMessage(msg.payload, sendResponse); 572 if (msg.expectsResponse)
609 // Return true to indicate that we want to call 573 {
610 // sendResponse asynchronously 574 sender.page.sendMessage(msg.payload, sendResponse);
611 return true; 575 return true;
612 } 576 }
613 break; 577
614 default: 578 sender.page.sendMessage(msg.payload);
615 sendResponse({}); 579 }
616 break; 580 break;
617 } 581 }
618 }); 582 });
619 583
620 // update icon when page changes location 584 // update icon when page changes location
621 ext.pages.onLoading.addListener(function(page) 585 ext.pages.onLoading.addListener(function(page)
622 { 586 {
623 page.sendMessage({type: "clickhide-deactivate"}); 587 page.sendMessage({type: "clickhide-deactivate"});
624 refreshIconAndContextMenu(page); 588 refreshIconAndContextMenu(page);
625 }); 589 });
626 590
627 setTimeout(function() 591 setTimeout(function()
628 { 592 {
629 var notificationToShow = Notification.getNextToShow(); 593 var notificationToShow = NotificationStorage.getNextToShow();
630 if (notificationToShow) 594 if (notificationToShow)
631 showNotification(notificationToShow); 595 showNotification(notificationToShow);
632 }, 3 * 60 * 1000); 596 }, 3 * 60 * 1000);
LEFTRIGHT

Powered by Google App Engine
This is Rietveld