| OLD | NEW | 
|---|
| 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-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 | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
| 33   this.isFrameWhitelisted = isFrameWhitelisted; | 33   this.isFrameWhitelisted = isFrameWhitelisted; | 
| 34   this.processKey = processKey; | 34   this.processKey = processKey; | 
| 35   this.getKey = getKey; | 35   this.getKey = getKey; | 
| 36 } | 36 } | 
| 37 with(require("url")) | 37 with(require("url")) | 
| 38 { | 38 { | 
| 39   this.stringifyURL = stringifyURL; | 39   this.stringifyURL = stringifyURL; | 
| 40   this.isThirdParty = isThirdParty; | 40   this.isThirdParty = isThirdParty; | 
| 41   this.extractHostFromFrame = extractHostFromFrame; | 41   this.extractHostFromFrame = extractHostFromFrame; | 
| 42 } | 42 } | 
| 43 with(require("icon")) |  | 
| 44 { |  | 
| 45   this.updateIcon = updateIcon; |  | 
| 46   this.startIconAnimation = startIconAnimation; |  | 
| 47   this.stopIconAnimation = stopIconAnimation; |  | 
| 48 } |  | 
| 49 var FilterStorage = require("filterStorage").FilterStorage; | 43 var FilterStorage = require("filterStorage").FilterStorage; | 
| 50 var FilterNotifier = require("filterNotifier").FilterNotifier; | 44 var FilterNotifier = require("filterNotifier").FilterNotifier; | 
| 51 var ElemHide = require("elemHide").ElemHide; | 45 var ElemHide = require("elemHide").ElemHide; | 
| 52 var defaultMatcher = require("matcher").defaultMatcher; | 46 var defaultMatcher = require("matcher").defaultMatcher; | 
| 53 var Prefs = require("prefs").Prefs; | 47 var Prefs = require("prefs").Prefs; | 
| 54 var Synchronizer = require("synchronizer").Synchronizer; | 48 var Synchronizer = require("synchronizer").Synchronizer; | 
| 55 var Utils = require("utils").Utils; | 49 var Utils = require("utils").Utils; | 
| 56 var NotificationStorage = require("notification").Notification; |  | 
| 57 var initAntiAdblockNotification = require("antiadblockInit").initAntiAdblockNoti
     fication; |  | 
| 58 var parseFilters = require("filterValidation").parseFilters; | 50 var parseFilters = require("filterValidation").parseFilters; | 
| 59 var composeFilters = require("filterComposer").composeFilters; | 51 var composeFilters = require("filterComposer").composeFilters; | 
| 60 | 52 var updateIcon = require("icon").updateIcon; | 
| 61 // Chrome on Linux does not fully support chrome.notifications until version 35 | 53 var initNotifications = require("notificationHelper").initNotifications; | 
| 62 // https://code.google.com/p/chromium/issues/detail?id=291485 |  | 
| 63 var canUseChromeNotifications = (function() |  | 
| 64 { |  | 
| 65   var info = require("info"); |  | 
| 66   if (info.platform == "chromium" && "notifications" in chrome) |  | 
| 67   { |  | 
| 68     if (navigator.platform.indexOf("Linux") == -1) |  | 
| 69       return true; |  | 
| 70     if (Services.vc.compare(info.applicationVersion, "35") >= 0) |  | 
| 71       return true; |  | 
| 72   } |  | 
| 73   return false; |  | 
| 74 })(); |  | 
| 75 | 54 | 
| 76 var seenDataCorruption = false; | 55 var seenDataCorruption = false; | 
| 77 var filterlistsReinitialized = false; | 56 var filterlistsReinitialized = false; | 
| 78 | 57 | 
| 79 function init() | 58 function init() | 
| 80 { | 59 { | 
| 81   var filtersLoaded = false; | 60   var filtersLoaded = false; | 
| 82   var prefsLoaded = false; | 61   var prefsLoaded = false; | 
| 83 | 62 | 
| 84   var checkLoaded = function() | 63   var checkLoaded = function() | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 101       seenDataCorruption = previousVersion && FilterStorage.firstRun; | 80       seenDataCorruption = previousVersion && FilterStorage.firstRun; | 
| 102       Prefs.currentVersion = info.addonVersion; | 81       Prefs.currentVersion = info.addonVersion; | 
| 103       addSubscription(previousVersion); | 82       addSubscription(previousVersion); | 
| 104     } | 83     } | 
| 105 | 84 | 
| 106     // The "Hide placeholders" option has been removed from the UI in 1.8.8.1285 | 85     // The "Hide placeholders" option has been removed from the UI in 1.8.8.1285 | 
| 107     // So we reset the option for users updating from older versions. | 86     // So we reset the option for users updating from older versions. | 
| 108     if (previousVersion && Services.vc.compare(previousVersion, "1.8.8.1285") < 
     0) | 87     if (previousVersion && Services.vc.compare(previousVersion, "1.8.8.1285") < 
     0) | 
| 109       Prefs.hidePlaceholders = true; | 88       Prefs.hidePlaceholders = true; | 
| 110 | 89 | 
| 111     if (canUseChromeNotifications) | 90     initNotifications(); | 
| 112       initChromeNotifications(); |  | 
| 113     initAntiAdblockNotification(); |  | 
| 114 | 91 | 
| 115     // Update browser actions and context menus when whitelisting might have | 92     // Update browser actions and context menus when whitelisting might have | 
| 116     // changed. That is now when initally loading the filters and later when | 93     // changed. That is now when initally loading the filters and later when | 
| 117     // importing backups or saving filter changes. | 94     // importing backups or saving filter changes. | 
| 118     FilterNotifier.addListener(function(action) | 95     FilterNotifier.addListener(function(action) | 
| 119     { | 96     { | 
| 120       if (action == "load" || action == "save") | 97       if (action == "load" || action == "save") | 
| 121         refreshIconAndContextMenuForAllPages(); | 98         refreshIconAndContextMenuForAllPages(); | 
| 122     }); | 99     }); | 
| 123     refreshIconAndContextMenuForAllPages(); | 100     refreshIconAndContextMenuForAllPages(); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 143   FilterNotifier.addListener(onFilterAction); | 120   FilterNotifier.addListener(onFilterAction); | 
| 144   Prefs.onLoaded.addListener(onPrefsLoaded); | 121   Prefs.onLoaded.addListener(onPrefsLoaded); | 
| 145 } | 122 } | 
| 146 init(); | 123 init(); | 
| 147 | 124 | 
| 148 // Special-case domains for which we cannot use style-based hiding rules. | 125 // Special-case domains for which we cannot use style-based hiding rules. | 
| 149 // See http://crbug.com/68705. | 126 // See http://crbug.com/68705. | 
| 150 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"]; | 127 var noStyleRulesHosts = ["mail.google.com", "mail.yahoo.com", "www.google.com"]; | 
| 151 | 128 | 
| 152 var htmlPages = new ext.PageMap(); | 129 var htmlPages = new ext.PageMap(); | 
| 153 var activeNotification = null; |  | 
| 154 | 130 | 
| 155 var contextMenuItem = { | 131 var contextMenuItem = { | 
| 156   title: ext.i18n.getMessage("block_element"), | 132   title: ext.i18n.getMessage("block_element"), | 
| 157   contexts: ["image", "video", "audio"], | 133   contexts: ["image", "video", "audio"], | 
| 158   onclick: function(page) | 134   onclick: function(page) | 
| 159   { | 135   { | 
| 160     page.sendMessage({type: "clickhide-new-filter"}); | 136     page.sendMessage({type: "clickhide-new-filter"}); | 
| 161   } | 137   } | 
| 162 }; | 138 }; | 
| 163 | 139 | 
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 283   else | 259   else | 
| 284     notifyUser(); | 260     notifyUser(); | 
| 285 } | 261 } | 
| 286 | 262 | 
| 287 Prefs.onChanged.addListener(function(name) | 263 Prefs.onChanged.addListener(function(name) | 
| 288 { | 264 { | 
| 289   if (name == "shouldShowBlockElementMenu") | 265   if (name == "shouldShowBlockElementMenu") | 
| 290     refreshIconAndContextMenuForAllPages(); | 266     refreshIconAndContextMenuForAllPages(); | 
| 291 }); | 267 }); | 
| 292 | 268 | 
| 293 function prepareNotificationIconAndPopup() |  | 
| 294 { |  | 
| 295   var animateIcon = (activeNotification.type !== "question"); |  | 
| 296   activeNotification.onClicked = function() |  | 
| 297   { |  | 
| 298     if (animateIcon) |  | 
| 299       stopIconAnimation(); |  | 
| 300     notificationClosed(); |  | 
| 301   }; |  | 
| 302   if (animateIcon) |  | 
| 303     startIconAnimation(activeNotification.type); |  | 
| 304 } |  | 
| 305 |  | 
| 306 function openNotificationLinks() |  | 
| 307 { |  | 
| 308   if (activeNotification.links) |  | 
| 309   { |  | 
| 310     activeNotification.links.forEach(function(link) |  | 
| 311     { |  | 
| 312       ext.windows.getLastFocused(function(win) |  | 
| 313       { |  | 
| 314         win.openTab(Utils.getDocLink(link)); |  | 
| 315       }); |  | 
| 316     }); |  | 
| 317   } |  | 
| 318 } |  | 
| 319 |  | 
| 320 function notificationButtonClick(buttonIndex) |  | 
| 321 { |  | 
| 322   if (activeNotification.type === "question") |  | 
| 323   { |  | 
| 324     NotificationStorage.triggerQuestionListeners(activeNotification.id, buttonIn
     dex === 0); |  | 
| 325     NotificationStorage.markAsShown(activeNotification.id); |  | 
| 326     activeNotification.onClicked(); |  | 
| 327   } |  | 
| 328   else if (activeNotification.links && activeNotification.links[buttonIndex]) |  | 
| 329   { |  | 
| 330     ext.windows.getLastFocused(function(win) |  | 
| 331     { |  | 
| 332       win.openTab(Utils.getDocLink(activeNotification.links[buttonIndex])); |  | 
| 333     }); |  | 
| 334   } |  | 
| 335 } |  | 
| 336 |  | 
| 337 function notificationClosed() |  | 
| 338 { |  | 
| 339   activeNotification = null; |  | 
| 340 } |  | 
| 341 |  | 
| 342 function imgToBase64(url, callback) |  | 
| 343 { |  | 
| 344   var canvas = document.createElement("canvas"), |  | 
| 345   ctx = canvas.getContext("2d"), |  | 
| 346   img = new Image; |  | 
| 347   img.src = url; |  | 
| 348   img.onload = function() |  | 
| 349   { |  | 
| 350     canvas.height = img.height; |  | 
| 351     canvas.width = img.width; |  | 
| 352     ctx.drawImage(img, 0, 0); |  | 
| 353     callback(canvas.toDataURL("image/png")); |  | 
| 354     canvas = null; |  | 
| 355   }; |  | 
| 356 } |  | 
| 357 |  | 
| 358 function initChromeNotifications() |  | 
| 359 { |  | 
| 360   // Chrome hides notifications in notification center when clicked so we need t
     o clear them |  | 
| 361   function clearActiveNotification(notificationId) |  | 
| 362   { |  | 
| 363     if (activeNotification && activeNotification.type != "question" && !("links"
      in activeNotification)) |  | 
| 364       return; |  | 
| 365 |  | 
| 366     chrome.notifications.clear(notificationId, function(wasCleared) |  | 
| 367     { |  | 
| 368       if (wasCleared) |  | 
| 369         notificationClosed(); |  | 
| 370     }); |  | 
| 371   } |  | 
| 372 |  | 
| 373   chrome.notifications.onButtonClicked.addListener(function(notificationId, butt
     onIndex) |  | 
| 374   { |  | 
| 375     notificationButtonClick(buttonIndex); |  | 
| 376     clearActiveNotification(notificationId); |  | 
| 377   }); |  | 
| 378   chrome.notifications.onClicked.addListener(clearActiveNotification); |  | 
| 379   chrome.notifications.onClosed.addListener(notificationClosed); |  | 
| 380 } |  | 
| 381 |  | 
| 382 function showNotification(notification) |  | 
| 383 { |  | 
| 384   if (activeNotification && activeNotification.id === notification.id) |  | 
| 385     return; |  | 
| 386 |  | 
| 387   activeNotification = notification; |  | 
| 388   if (activeNotification.type === "critical" || activeNotification.type === "que
     stion") |  | 
| 389   { |  | 
| 390     var texts = NotificationStorage.getLocalizedTexts(notification); |  | 
| 391     var title = texts.title || ""; |  | 
| 392     var message = texts.message ? texts.message.replace(/<\/?(a|strong)>/g, "") 
     : ""; |  | 
| 393     var iconUrl = ext.getURL("icons/detailed/abp-128.png"); |  | 
| 394     var hasLinks = activeNotification.links && activeNotification.links.length >
      0; |  | 
| 395 |  | 
| 396     if (canUseChromeNotifications) |  | 
| 397     { |  | 
| 398       var opts = { |  | 
| 399         type: "basic", |  | 
| 400         title: title, |  | 
| 401         message: message, |  | 
| 402         buttons: [], |  | 
| 403         priority: 2 // We use the highest priority to prevent the notification f
     rom closing automatically |  | 
| 404       }; |  | 
| 405       if (activeNotification.type === "question") |  | 
| 406       { |  | 
| 407         opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt
     on_yes")}); |  | 
| 408         opts.buttons.push({title: ext.i18n.getMessage("overlay_notification_butt
     on_no")}); |  | 
| 409       } |  | 
| 410       else |  | 
| 411       { |  | 
| 412         var regex = /<a>(.*?)<\/a>/g; |  | 
| 413         var plainMessage = texts.message || ""; |  | 
| 414         var match; |  | 
| 415         while (match = regex.exec(plainMessage)) |  | 
| 416           opts.buttons.push({title: match[1]}); |  | 
| 417       } |  | 
| 418 |  | 
| 419       imgToBase64(iconUrl, function(iconData) |  | 
| 420       { |  | 
| 421         opts["iconUrl"] = iconData; |  | 
| 422         chrome.notifications.create("", opts, function() {}); |  | 
| 423       }); |  | 
| 424     } |  | 
| 425     else if ("Notification" in window && activeNotification.type !== "question") |  | 
| 426     { |  | 
| 427       if (hasLinks) |  | 
| 428         message += " " + ext.i18n.getMessage("notification_without_buttons"); |  | 
| 429 |  | 
| 430       imgToBase64(iconUrl, function(iconData) |  | 
| 431       { |  | 
| 432         var notification = new Notification( |  | 
| 433           title, |  | 
| 434           { |  | 
| 435             lang: Utils.appLocale, |  | 
| 436             dir: ext.i18n.getMessage("@@bidi_dir"), |  | 
| 437             body: message, |  | 
| 438             icon: iconData |  | 
| 439           } |  | 
| 440         ); |  | 
| 441 |  | 
| 442         notification.addEventListener("click", openNotificationLinks); |  | 
| 443         notification.addEventListener("close", notificationClosed); |  | 
| 444       }); |  | 
| 445     } |  | 
| 446     else |  | 
| 447     { |  | 
| 448       var message = title + "\n" + message; |  | 
| 449       if (hasLinks) |  | 
| 450         message += "\n\n" + ext.i18n.getMessage("notification_with_buttons"); |  | 
| 451 |  | 
| 452       var approved = confirm(message); |  | 
| 453       if (activeNotification.type === "question") |  | 
| 454         notificationButtonClick(approved ? 0 : 1); |  | 
| 455       else if (approved) |  | 
| 456         openNotificationLinks(); |  | 
| 457     } |  | 
| 458   } |  | 
| 459   prepareNotificationIconAndPopup(); |  | 
| 460 } |  | 
| 461 |  | 
| 462 // This is a hack to speedup loading of the options page on Safari. | 269 // This is a hack to speedup loading of the options page on Safari. | 
| 463 // Once we replaced the background page proxy with message passing | 270 // Once we replaced the background page proxy with message passing | 
| 464 // this global function should removed. | 271 // this global function should removed. | 
| 465 function getUserFilters() | 272 function getUserFilters() | 
| 466 { | 273 { | 
| 467   var filters = []; | 274   var filters = []; | 
| 468   var exceptions = []; | 275   var exceptions = []; | 
| 469 | 276 | 
| 470   for (var i = 0; i < FilterStorage.subscriptions.length; i++) | 277   for (var i = 0; i < FilterStorage.subscriptions.length; i++) | 
| 471   { | 278   { | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 610       break; | 417       break; | 
| 611   } | 418   } | 
| 612 }); | 419 }); | 
| 613 | 420 | 
| 614 // update icon when page changes location | 421 // update icon when page changes location | 
| 615 ext.pages.onLoading.addListener(function(page) | 422 ext.pages.onLoading.addListener(function(page) | 
| 616 { | 423 { | 
| 617   page.sendMessage({type: "clickhide-deactivate"}); | 424   page.sendMessage({type: "clickhide-deactivate"}); | 
| 618   refreshIconAndContextMenu(page); | 425   refreshIconAndContextMenu(page); | 
| 619 }); | 426 }); | 
| 620 |  | 
| 621 setTimeout(function() |  | 
| 622 { |  | 
| 623   var notificationToShow = NotificationStorage.getNextToShow(); |  | 
| 624   if (notificationToShow) |  | 
| 625     showNotification(notificationToShow); |  | 
| 626 }, 3 * 60 * 1000); |  | 
| OLD | NEW | 
|---|