| 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-2017 eyeo GmbH | 3  * Copyright (C) 2006-2017 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 /* globals checkShareResource, getDocLink, i18nFormatDateTime, openSharePopup, | 18 /* globals checkShareResource, getDocLink, i18nFormatDateTime, openSharePopup, | 
| 19            setLinks, E */ | 19            setLinks, E */ | 
| 20 | 20 | 
| 21 "use strict"; | 21 "use strict"; | 
| 22 | 22 | 
| 23 { | 23 { | 
| 24   let subscriptionsMap = Object.create(null); | 24   let subscriptionsMap = Object.create(null); | 
| 25   let filtersMap = Object.create(null); | 25   let filtersMap = Object.create(null); | 
| 26   let collections = Object.create(null); | 26   let collections = Object.create(null); | 
| 27   let acceptableAdsUrl = null; | 27   let acceptableAdsUrl = null; | 
|  | 28   let acceptableAdsPrivacyUrl = null; | 
| 28   let isCustomFiltersLoaded = false; | 29   let isCustomFiltersLoaded = false; | 
| 29   let {getMessage} = ext.i18n; | 30   let {getMessage} = ext.i18n; | 
| 30   let customFilters = []; | 31   let customFilters = []; | 
| 31   let filterErrors = new Map([ | 32   let filterErrors = new Map([ | 
| 32     ["synchronize_invalid_url", | 33     ["synchronize_invalid_url", | 
| 33      "options_filterList_lastDownload_invalidURL"], | 34      "options_filterList_lastDownload_invalidURL"], | 
| 34     ["synchronize_connection_error", | 35     ["synchronize_connection_error", | 
| 35      "options_filterList_lastDownload_connectionError"], | 36      "options_filterList_lastDownload_connectionError"], | 
| 36     ["synchronize_invalid_data", | 37     ["synchronize_invalid_data", | 
| 37      "options_filterList_lastDownload_invalidData"], | 38      "options_filterList_lastDownload_invalidData"], | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 76   { | 77   { | 
| 77     let access = (item.url || item.text).replace(/'/g, "\\'"); | 78     let access = (item.url || item.text).replace(/'/g, "\\'"); | 
| 78     return function(container) | 79     return function(container) | 
| 79     { | 80     { | 
| 80       return container.querySelector("[data-access='" + access + "']"); | 81       return container.querySelector("[data-access='" + access + "']"); | 
| 81     }; | 82     }; | 
| 82   }; | 83   }; | 
| 83 | 84 | 
| 84   Collection.prototype._getItemTitle = function(item, i) | 85   Collection.prototype._getItemTitle = function(item, i) | 
| 85   { | 86   { | 
| 86     if (item.url == acceptableAdsUrl) |  | 
| 87       return getMessage("options_acceptableAds_description"); |  | 
| 88     if (this.details[i].useOriginalTitle && item.originalTitle) | 87     if (this.details[i].useOriginalTitle && item.originalTitle) | 
| 89       return item.originalTitle; | 88       return item.originalTitle; | 
| 90     return item.title || item.url || item.text; | 89     return item.title || item.url || item.text; | 
| 91   }; | 90   }; | 
| 92 | 91 | 
| 93   Collection.prototype._sortItems = function() | 92   Collection.prototype._sortItems = function() | 
| 94   { | 93   { | 
| 95     this.items.sort((a, b) => | 94     this.items.sort((a, b) => | 
| 96     { | 95     { | 
| 97       // Make sure that Acceptable Ads is always last, since it cannot be | 96       // Make sure that Acceptable Ads is always last, since it cannot be | 
| 98       // disabled, but only be removed. That way it's grouped together with | 97       // disabled, but only be removed. That way it's grouped together with | 
| 99       // the "Own filter list" which cannot be disabled either at the bottom | 98       // the "Own filter list" which cannot be disabled either at the bottom | 
| 100       // of the filter lists in the Advanced tab. | 99       // of the filter lists in the Advanced tab. | 
| 101       if (a.url == acceptableAdsUrl) | 100       if (isAcceptableAds(a.url)) | 
| 102         return 1; | 101         return 1; | 
| 103       if (b.url == acceptableAdsUrl) | 102       if (isAcceptableAds(b.url)) | 
| 104         return -1; | 103         return -1; | 
| 105 | 104 | 
| 106       // Make sure that newly added entries always appear on top in descending | 105       // Make sure that newly added entries always appear on top in descending | 
| 107       // chronological order | 106       // chronological order | 
| 108       let aTimestamp = a[timestampUI] || 0; | 107       let aTimestamp = a[timestampUI] || 0; | 
| 109       let bTimestamp = b[timestampUI] || 0; | 108       let bTimestamp = b[timestampUI] || 0; | 
| 110       if (aTimestamp || bTimestamp) | 109       if (aTimestamp || bTimestamp) | 
| 111         return bTimestamp - aTimestamp; | 110         return bTimestamp - aTimestamp; | 
| 112 | 111 | 
| 113       let aTitle = this._getItemTitle(a, 0).toLowerCase(); | 112       let aTitle = this._getItemTitle(a, 0).toLowerCase(); | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 127     { | 126     { | 
| 128       let detail = this.details[j]; | 127       let detail = this.details[j]; | 
| 129       let table = E(detail.id); | 128       let table = E(detail.id); | 
| 130       let template = table.querySelector("template"); | 129       let template = table.querySelector("template"); | 
| 131       let listItem = document.createElement("li"); | 130       let listItem = document.createElement("li"); | 
| 132       listItem.appendChild(document.importNode(template.content, true)); | 131       listItem.appendChild(document.importNode(template.content, true)); | 
| 133       listItem.setAttribute("aria-label", this._getItemTitle(item, j)); | 132       listItem.setAttribute("aria-label", this._getItemTitle(item, j)); | 
| 134       listItem.setAttribute("data-access", item.url || item.text); | 133       listItem.setAttribute("data-access", item.url || item.text); | 
| 135       listItem.setAttribute("role", "section"); | 134       listItem.setAttribute("role", "section"); | 
| 136 | 135 | 
| 137       let label = listItem.querySelector(".display"); | 136       let tooltip = listItem.querySelector("[data-tooltip]"); | 
| 138       if (item.recommended && label.hasAttribute("data-tooltip")) | 137       if (tooltip) | 
| 139       { | 138       { | 
| 140         let tooltipId = label.getAttribute("data-tooltip"); | 139         let tooltipId = tooltip.getAttribute("data-tooltip"); | 
| 141         tooltipId = tooltipId.replace("%value%", item.recommended); | 140         tooltipId = tooltipId.replace("%value%", item.recommended); | 
| 142         label.setAttribute("data-tooltip", tooltipId); | 141         if (getMessage(tooltipId)) | 
|  | 142         { | 
|  | 143           tooltip.setAttribute("data-tooltip", tooltipId); | 
|  | 144         } | 
|  | 145         else | 
|  | 146         { | 
|  | 147           tooltip.parentNode.removeChild(tooltip); | 
|  | 148         } | 
| 143       } | 149       } | 
| 144 | 150 | 
| 145       for (let control of listItem.querySelectorAll(".control")) | 151       for (let control of listItem.querySelectorAll(".control")) | 
| 146       { | 152       { | 
| 147         if (control.hasAttribute("title")) | 153         if (control.hasAttribute("title")) | 
| 148         { | 154         { | 
| 149           let titleValue = getMessage(control.getAttribute("title")); | 155           let titleValue = getMessage(control.getAttribute("title")); | 
| 150           control.setAttribute("title", titleValue); | 156           control.setAttribute("title", titleValue); | 
| 151         } | 157         } | 
| 152       } | 158       } | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 207     this._sortItems(); | 213     this._sortItems(); | 
| 208     let access = (item.url || item.text).replace(/'/g, "\\'"); | 214     let access = (item.url || item.text).replace(/'/g, "\\'"); | 
| 209     for (let i = 0; i < this.details.length; i++) | 215     for (let i = 0; i < this.details.length; i++) | 
| 210     { | 216     { | 
| 211       let table = E(this.details[i].id); | 217       let table = E(this.details[i].id); | 
| 212       let element = table.querySelector("[data-access='" + access + "']"); | 218       let element = table.querySelector("[data-access='" + access + "']"); | 
| 213       if (!element) | 219       if (!element) | 
| 214         continue; | 220         continue; | 
| 215 | 221 | 
| 216       let title = this._getItemTitle(item, i); | 222       let title = this._getItemTitle(item, i); | 
| 217       element.querySelector(".display").textContent = title; | 223       let displays = element.querySelectorAll(".display"); | 
|  | 224       for (let j = 0; j < displays.length; j++) | 
|  | 225         displays[j].textContent = title; | 
|  | 226 | 
| 218       element.setAttribute("aria-label", title); | 227       element.setAttribute("aria-label", title); | 
| 219       if (this.details[i].searchable) | 228       if (this.details[i].searchable) | 
| 220         element.setAttribute("data-search", title.toLowerCase()); | 229         element.setAttribute("data-search", title.toLowerCase()); | 
| 221       let control = element.querySelector(".control[role='checkbox']"); | 230       let control = element.querySelector(".control[role='checkbox']"); | 
| 222       if (control) | 231       if (control) | 
| 223       { | 232       { | 
| 224         control.setAttribute("aria-checked", item.disabled == false); | 233         control.setAttribute("aria-checked", item.disabled == false); | 
| 225         if (item.url == acceptableAdsUrl && this == collections.filterLists) | 234         if (isAcceptableAds(item.url) && this == collections.filterLists) | 
| 226           control.disabled = true; | 235           control.disabled = true; | 
| 227       } | 236       } | 
| 228 | 237 | 
| 229       let lastUpdateElement = element.querySelector(".last-update"); | 238       let lastUpdateElement = element.querySelector(".last-update"); | 
| 230       if (lastUpdateElement) | 239       if (lastUpdateElement) | 
| 231       { | 240       { | 
| 232         let message = element.querySelector(".message"); | 241         let message = element.querySelector(".message"); | 
| 233         if (item.isDownloading) | 242         if (item.isDownloading) | 
| 234         { | 243         { | 
| 235           let text = getMessage("options_filterList_lastDownload_inProgress"); | 244           let text = getMessage("options_filterList_lastDownload_inProgress"); | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 323     index += (index == focusables.length - 1) ? -1 : 1; | 332     index += (index == focusables.length - 1) ? -1 : 1; | 
| 324 | 333 | 
| 325     let nextElement = focusables[index]; | 334     let nextElement = focusables[index]; | 
| 326     if (!nextElement) | 335     if (!nextElement) | 
| 327       return false; | 336       return false; | 
| 328 | 337 | 
| 329     nextElement.focus(); | 338     nextElement.focus(); | 
| 330     return true; | 339     return true; | 
| 331   } | 340   } | 
| 332 | 341 | 
| 333   collections.popular = new Collection([ | 342   collections.protection = new Collection([ | 
| 334     { | 343     { | 
| 335       id: "recommend-list-table" | 344       id: "recommend-protection-list-table" | 
| 336     } | 345     } | 
| 337   ]); | 346   ]); | 
| 338   collections.langs = new Collection([ | 347   collections.langs = new Collection([ | 
| 339     { | 348     { | 
| 340       id: "blocking-languages-table", | 349       id: "blocking-languages-table", | 
| 341       emptyText: ["options_dialog_language_added_empty"] | 350       emptyText: ["options_language_empty"] | 
| 342     }, |  | 
| 343     { |  | 
| 344       id: "blocking-languages-dialog-table", |  | 
| 345       emptyText: ["options_dialog_language_added_empty"] |  | 
| 346     } | 351     } | 
| 347   ]); | 352   ]); | 
| 348   collections.allLangs = new Collection([ | 353   collections.allLangs = new Collection([ | 
| 349     { | 354     { | 
| 350       id: "all-lang-table", | 355       id: "all-lang-table-add", | 
| 351       emptyText: ["options_dialog_language_other_empty"], | 356       emptyText: ["options_dialog_language_other_empty"] | 
| 352       searchable: true |  | 
| 353     } |  | 
| 354   ]); |  | 
| 355   collections.acceptableAds = new Collection([ |  | 
| 356     { |  | 
| 357       id: "acceptableads-table" |  | 
| 358     } | 357     } | 
| 359   ]); | 358   ]); | 
| 360   collections.custom = new Collection([ | 359   collections.custom = new Collection([ | 
| 361     { | 360     { | 
| 362       id: "custom-list-table" | 361       id: "custom-list-table" | 
| 363     } | 362     } | 
| 364   ]); | 363   ]); | 
| 365   collections.whitelist = new Collection([ | 364   collections.whitelist = new Collection([ | 
| 366     { | 365     { | 
| 367       id: "whitelisting-table", | 366       id: "whitelisting-table", | 
| 368       emptyText: ["options_whitelist_empty_1", "options_whitelist_empty_2"] | 367       emptyText: ["options_whitelist_empty_1", "options_whitelist_empty_2"] | 
| 369     } | 368     } | 
| 370   ]); | 369   ]); | 
| 371   collections.filterLists = new Collection([ | 370   collections.filterLists = new Collection([ | 
| 372     { | 371     { | 
| 373       id: "all-filter-lists-table", | 372       id: "all-filter-lists-table", | 
| 374       useOriginalTitle: true | 373       useOriginalTitle: true | 
| 375     } | 374     } | 
| 376   ]); | 375   ]); | 
| 377 | 376 | 
| 378   function toggleShowLanguage(subscription) | 377   function addSubscription(subscription) | 
| 379   { | 378   { | 
| 380     if (subscription.recommended == "ads") | 379     let collection = null; | 
|  | 380     if (subscription.recommended) | 
| 381     { | 381     { | 
| 382       if (subscription.disabled) | 382       if (subscription.recommended == "ads") | 
| 383       { | 383       { | 
|  | 384         if (subscription.disabled == false) | 
|  | 385           collection = collections.langs; | 
|  | 386 | 
| 384         collections.allLangs.addItem(subscription); | 387         collections.allLangs.addItem(subscription); | 
| 385         collections.langs.removeItem(subscription); |  | 
| 386       } | 388       } | 
| 387       else | 389       else | 
| 388       { | 390       { | 
| 389         collections.allLangs.removeItem(subscription); | 391         collection = collections.protection; | 
| 390         collections.langs.addItem(subscription); |  | 
| 391       } | 392       } | 
| 392     } | 393     } | 
| 393   } | 394     else if (!isAcceptableAds(subscription.url)) | 
|  | 395     { | 
|  | 396       collection = collections.custom; | 
|  | 397     } | 
| 394 | 398 | 
| 395   function addSubscription(subscription) | 399     if (collection) | 
| 396   { | 400       collection.addItem(subscription); | 
| 397     let collection; |  | 
| 398     if (subscription.recommended) |  | 
| 399     { |  | 
| 400       if (subscription.recommended != "ads") |  | 
| 401         collection = collections.popular; |  | 
| 402       else if (subscription.disabled == false) |  | 
| 403         collection = collections.langs; |  | 
| 404       else |  | 
| 405         collection = collections.allLangs; |  | 
| 406     } |  | 
| 407     else if (subscription.url == acceptableAdsUrl) |  | 
| 408       collection = collections.acceptableAds; |  | 
| 409     else |  | 
| 410       collection = collections.custom; |  | 
| 411 | 401 | 
| 412     collection.addItem(subscription); |  | 
| 413     subscriptionsMap[subscription.url] = subscription; | 402     subscriptionsMap[subscription.url] = subscription; | 
| 414     toggleShowLanguage(subscription); |  | 
| 415     updateTooltips(); | 403     updateTooltips(); | 
| 416   } | 404   } | 
| 417 | 405 | 
| 418   function updateSubscription(subscription) | 406   function updateSubscription(subscription) | 
| 419   { | 407   { | 
| 420     for (let name in collections) | 408     for (let name in collections) | 
| 421       collections[name].updateItem(subscription); | 409       collections[name].updateItem(subscription); | 
| 422 | 410 | 
| 423     toggleShowLanguage(subscription); | 411     if (subscription.recommended == "ads") | 
|  | 412     { | 
|  | 413       if (subscription.disabled) | 
|  | 414         collections.langs.removeItem(subscription); | 
|  | 415       else | 
|  | 416         collections.langs.addItem(subscription); | 
|  | 417     } | 
|  | 418     else if (!subscription.recommended && !isAcceptableAds(subscription.url)) | 
|  | 419     { | 
|  | 420       if (subscription.disabled == false) | 
|  | 421       { | 
|  | 422         collections.custom.addItem(subscription); | 
|  | 423         updateTooltips(); | 
|  | 424       } | 
|  | 425       else | 
|  | 426       { | 
|  | 427         collections.custom.removeItem(subscription); | 
|  | 428       } | 
|  | 429     } | 
| 424   } | 430   } | 
| 425 | 431 | 
| 426   function updateFilter(filter) | 432   function updateFilter(filter) | 
| 427   { | 433   { | 
| 428     let match = filter.text.match(whitelistedDomainRegexp); | 434     let match = filter.text.match(whitelistedDomainRegexp); | 
| 429     if (match && !filtersMap[filter.text]) | 435     if (match && !filtersMap[filter.text]) | 
| 430     { | 436     { | 
| 431       filter.title = match[1]; | 437       filter.title = match[1]; | 
| 432       collections.whitelist.addItem(filter); | 438       collections.whitelist.addItem(filter); | 
| 433     } | 439     } | 
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 554         let dialog = E("dialog-content-predefined"); | 560         let dialog = E("dialog-content-predefined"); | 
| 555         let title = dialog.querySelector("h3").textContent; | 561         let title = dialog.querySelector("h3").textContent; | 
| 556         let url = dialog.querySelector(".url").textContent; | 562         let url = dialog.querySelector(".url").textContent; | 
| 557         addEnableSubscription(url, title); | 563         addEnableSubscription(url, title); | 
| 558         closeDialog(); | 564         closeDialog(); | 
| 559         break; | 565         break; | 
| 560       } | 566       } | 
| 561       case "cancel-custom-filters": | 567       case "cancel-custom-filters": | 
| 562         setCustomFiltersView("read"); | 568         setCustomFiltersView("read"); | 
| 563         break; | 569         break; | 
|  | 570       case "change-language-subscription": | 
|  | 571         for (let key in subscriptionsMap) | 
|  | 572         { | 
|  | 573           let subscription = subscriptionsMap[key]; | 
|  | 574           let subscriptionType = subscription.recommended; | 
|  | 575           if (subscriptionType == "ads" && subscription.disabled == false) | 
|  | 576           { | 
|  | 577             ext.backgroundPage.sendMessage({ | 
|  | 578               type: "subscriptions.remove", | 
|  | 579               url: subscription.url | 
|  | 580             }); | 
|  | 581             ext.backgroundPage.sendMessage({ | 
|  | 582               type: "subscriptions.add", | 
|  | 583               url: findParentData(element, "access", false) | 
|  | 584             }); | 
|  | 585             break; | 
|  | 586           } | 
|  | 587         } | 
|  | 588         break; | 
| 564       case "close-dialog": | 589       case "close-dialog": | 
| 565         closeDialog(); | 590         closeDialog(); | 
| 566         break; | 591         break; | 
| 567       case "edit-custom-filters": | 592       case "edit-custom-filters": | 
| 568         setCustomFiltersView("write"); | 593         setCustomFiltersView("write"); | 
| 569         break; | 594         break; | 
| 570       case "import-subscription": { | 595       case "import-subscription": { | 
| 571         let url = E("blockingList-textbox").value; | 596         let url = E("blockingList-textbox").value; | 
| 572         addEnableSubscription(url); | 597         addEnableSubscription(url); | 
| 573         closeDialog(); | 598         closeDialog(); | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 605         sendMessageHandleErrors({ | 630         sendMessageHandleErrors({ | 
| 606           type: "filters.importRaw", | 631           type: "filters.importRaw", | 
| 607           text: E("custom-filters-raw").value, | 632           text: E("custom-filters-raw").value, | 
| 608           removeExisting: true | 633           removeExisting: true | 
| 609         }, | 634         }, | 
| 610         () => | 635         () => | 
| 611         { | 636         { | 
| 612           setCustomFiltersView("read"); | 637           setCustomFiltersView("read"); | 
| 613         }); | 638         }); | 
| 614         break; | 639         break; | 
|  | 640       case "switch-acceptable-ads": | 
|  | 641         let {value} = element; | 
|  | 642         ext.backgroundPage.sendMessage({ | 
|  | 643           type: value == "privacy" ? "subscriptions.add" : | 
|  | 644             "subscriptions.remove", | 
|  | 645           url: acceptableAdsPrivacyUrl | 
|  | 646         }); | 
|  | 647         ext.backgroundPage.sendMessage({ | 
|  | 648           type: value == "ads" ? "subscriptions.add" : "subscriptions.remove", | 
|  | 649           url: acceptableAdsUrl | 
|  | 650         }); | 
|  | 651         break; | 
| 615       case "switch-tab": | 652       case "switch-tab": | 
| 616         let tabId = findParentData(element, "tab", false); | 653         let tabId = findParentData(element, "tab", false); | 
| 617         switchTab(tabId); | 654         switchTab(tabId); | 
| 618         break; | 655         break; | 
| 619       case "toggle-disable-subscription": | 656       case "toggle-disable-subscription": | 
| 620         ext.backgroundPage.sendMessage({ | 657         ext.backgroundPage.sendMessage({ | 
| 621           type: "subscriptions.toggle", | 658           type: "subscriptions.toggle", | 
| 622           keepInstalled: true, | 659           keepInstalled: true, | 
| 623           url: findParentData(element, "access", false) | 660           url: findParentData(element, "access", false) | 
| 624         }); | 661         }); | 
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 781       let tabId = tabIds.slice(0, i + 1).join("-"); | 818       let tabId = tabIds.slice(0, i + 1).join("-"); | 
| 782       tabContent = selectTabItem(tabId, tabContent, true); | 819       tabContent = selectTabItem(tabId, tabContent, true); | 
| 783       if (!tabContent) | 820       if (!tabContent) | 
| 784         break; | 821         break; | 
| 785     } | 822     } | 
| 786   } | 823   } | 
| 787 | 824 | 
| 788   function onDOMLoaded() | 825   function onDOMLoaded() | 
| 789   { | 826   { | 
| 790     populateLists(); | 827     populateLists(); | 
| 791     function onFindLanguageKeyUp() |  | 
| 792     { |  | 
| 793       let searchStyle = E("search-style"); |  | 
| 794       if (!this.value) |  | 
| 795         searchStyle.innerHTML = ""; |  | 
| 796       else |  | 
| 797       { |  | 
| 798         searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + |  | 
| 799           this.value.toLowerCase() + "\"]) { display: none; }"; |  | 
| 800       } |  | 
| 801     } |  | 
| 802 | 828 | 
| 803     // Initialize navigation sidebar | 829     // Initialize navigation sidebar | 
| 804     ext.backgroundPage.sendMessage({ | 830     ext.backgroundPage.sendMessage({ | 
| 805       type: "app.get", | 831       type: "app.get", | 
| 806       what: "addonVersion" | 832       what: "addonVersion" | 
| 807     }, | 833     }, | 
| 808     (addonVersion) => | 834     (addonVersion) => | 
| 809     { | 835     { | 
| 810       E("abp-version").textContent = addonVersion; | 836       E("abp-version").textContent = addonVersion; | 
| 811     }); | 837     }); | 
| 812     getDocLink("releases", (link) => | 838     getDocLink("releases", (link) => | 
| 813     { | 839     { | 
| 814       E("link-version").setAttribute("href", link); | 840       E("link-version").setAttribute("href", link); | 
| 815     }); | 841     }); | 
| 816 | 842 | 
| 817     updateShareLink(); | 843     updateShareLink(); | 
| 818     updateTooltips(); | 844     updateTooltips(); | 
| 819 | 845 | 
| 820     // Initialize interactive UI elements | 846     // Initialize interactive UI elements | 
| 821     document.body.addEventListener("click", onClick, false); | 847     document.body.addEventListener("click", onClick, false); | 
| 822     document.body.addEventListener("keyup", onKeyUp, false); | 848     document.body.addEventListener("keyup", onKeyUp, false); | 
| 823     let placeholderValue = getMessage("options_dialog_language_find"); |  | 
| 824     E("find-language").setAttribute("placeholder", placeholderValue); |  | 
| 825     E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); |  | 
| 826     let exampleValue = getMessage("options_whitelist_placeholder_example", | 849     let exampleValue = getMessage("options_whitelist_placeholder_example", | 
| 827       ["www.example.com"]); | 850       ["www.example.com"]); | 
| 828     E("whitelisting-textbox").setAttribute("placeholder", exampleValue); | 851     E("whitelisting-textbox").setAttribute("placeholder", exampleValue); | 
| 829     E("whitelisting-textbox").addEventListener("keyup", (e) => | 852     E("whitelisting-textbox").addEventListener("keyup", (e) => | 
| 830     { | 853     { | 
| 831       E("whitelisting-add-button").disabled = !e.target.value; | 854       E("whitelisting-add-button").disabled = !e.target.value; | 
| 832     }, false); | 855     }, false); | 
| 833 | 856 | 
|  | 857     getDocLink("acceptable_ads_criteria", (link) => | 
|  | 858     { | 
|  | 859       setLinks("enable-aa-description", link); | 
|  | 860     }); | 
|  | 861 | 
| 834     // Advanced tab | 862     // Advanced tab | 
| 835     let customize = document.querySelectorAll("#customize li[data-pref]"); | 863     let customize = document.querySelectorAll("#customize li[data-pref]"); | 
| 836     customize = Array.prototype.map.call(customize, (checkbox) => | 864     customize = Array.prototype.map.call(customize, (checkbox) => | 
| 837     { | 865     { | 
| 838       return checkbox.getAttribute("data-pref"); | 866       return checkbox.getAttribute("data-pref"); | 
| 839     }); | 867     }); | 
| 840     for (let key of customize) | 868     for (let key of customize) | 
| 841     { | 869     { | 
| 842       getPref(key, (value) => | 870       getPref(key, (value) => | 
| 843       { | 871       { | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 962 | 990 | 
| 963   function closeDialog() | 991   function closeDialog() | 
| 964   { | 992   { | 
| 965     let dialog = E("dialog"); | 993     let dialog = E("dialog"); | 
| 966     dialog.setAttribute("aria-hidden", true); | 994     dialog.setAttribute("aria-hidden", true); | 
| 967     dialog.removeAttribute("aria-labelledby"); | 995     dialog.removeAttribute("aria-labelledby"); | 
| 968     document.body.removeAttribute("data-dialog"); | 996     document.body.removeAttribute("data-dialog"); | 
| 969     focusedBeforeDialog.focus(); | 997     focusedBeforeDialog.focus(); | 
| 970   } | 998   } | 
| 971 | 999 | 
|  | 1000   function setAcceptableAds() | 
|  | 1001   { | 
|  | 1002     let option = "none"; | 
|  | 1003     document.forms["acceptable-ads"].classList.remove("show-dnt-notification"); | 
|  | 1004     if (acceptableAdsUrl in subscriptionsMap) | 
|  | 1005     { | 
|  | 1006       option = "ads"; | 
|  | 1007     } | 
|  | 1008     else if (acceptableAdsPrivacyUrl in subscriptionsMap) | 
|  | 1009     { | 
|  | 1010       option = "privacy"; | 
|  | 1011 | 
|  | 1012       if (!navigator.doNotTrack) | 
|  | 1013         document.forms["acceptable-ads"].classList.add("show-dnt-notification"); | 
|  | 1014     } | 
|  | 1015     document.forms["acceptable-ads"]["acceptable-ads"].value = option; | 
|  | 1016   } | 
|  | 1017 | 
|  | 1018   function isAcceptableAds(url) | 
|  | 1019   { | 
|  | 1020     return url == acceptableAdsUrl || url == acceptableAdsPrivacyUrl; | 
|  | 1021   } | 
|  | 1022 | 
| 972   function populateLists() | 1023   function populateLists() | 
| 973   { | 1024   { | 
| 974     subscriptionsMap = Object.create(null); | 1025     subscriptionsMap = Object.create(null); | 
| 975     filtersMap = Object.create(null); | 1026     filtersMap = Object.create(null); | 
| 976 | 1027 | 
| 977     // Empty collections and lists | 1028     // Empty collections and lists | 
| 978     for (let property in collections) | 1029     for (let property in collections) | 
| 979       collections[property].clearAll(); | 1030       collections[property].clearAll(); | 
| 980 | 1031 | 
| 981     ext.backgroundPage.sendMessage({ | 1032     ext.backgroundPage.sendMessage({ | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 1007       key: "subscriptions_exceptionsurl" | 1058       key: "subscriptions_exceptionsurl" | 
| 1008     }, | 1059     }, | 
| 1009     (url) => | 1060     (url) => | 
| 1010     { | 1061     { | 
| 1011       acceptableAdsUrl = url; | 1062       acceptableAdsUrl = url; | 
| 1012       addSubscription({ | 1063       addSubscription({ | 
| 1013         url: acceptableAdsUrl, | 1064         url: acceptableAdsUrl, | 
| 1014         disabled: true | 1065         disabled: true | 
| 1015       }); | 1066       }); | 
| 1016 | 1067 | 
| 1017       // Load user subscriptions |  | 
| 1018       ext.backgroundPage.sendMessage({ | 1068       ext.backgroundPage.sendMessage({ | 
| 1019         type: "subscriptions.get", | 1069         type: "prefs.get", | 
| 1020         downloadable: true | 1070         key: "subscriptions_exceptionsurl_privacy" | 
| 1021       }, | 1071       }, | 
| 1022       (subscriptions) => | 1072       (urlPrivacy) => | 
| 1023       { | 1073       { | 
| 1024         for (let subscription of subscriptions) | 1074         acceptableAdsPrivacyUrl = urlPrivacy; | 
| 1025           onSubscriptionMessage("added", subscription); | 1075 | 
|  | 1076         // Load user subscriptions | 
|  | 1077         ext.backgroundPage.sendMessage({ | 
|  | 1078           type: "subscriptions.get", | 
|  | 1079           downloadable: true | 
|  | 1080         }, | 
|  | 1081         (subscriptions) => | 
|  | 1082         { | 
|  | 1083           for (let subscription of subscriptions) | 
|  | 1084             onSubscriptionMessage("added", subscription); | 
|  | 1085         }); | 
| 1026       }); | 1086       }); | 
| 1027     }); | 1087     }); | 
| 1028   } | 1088   } | 
| 1029 | 1089 | 
| 1030   function addWhitelistedDomain() | 1090   function addWhitelistedDomain() | 
| 1031   { | 1091   { | 
| 1032     let domain = E("whitelisting-textbox"); | 1092     let domain = E("whitelisting-textbox"); | 
| 1033     for (let whitelistItem of collections.whitelist.items) | 1093     for (let whitelistItem of collections.whitelist.items) | 
| 1034     { | 1094     { | 
| 1035       if (whitelistItem.title == domain.value) | 1095       if (whitelistItem.title == domain.value) | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1123       case "lastDownload": | 1183       case "lastDownload": | 
| 1124       case "title": | 1184       case "title": | 
| 1125         updateSubscription(subscription); | 1185         updateSubscription(subscription); | 
| 1126         break; | 1186         break; | 
| 1127       case "added": | 1187       case "added": | 
| 1128         if (subscription.url in subscriptionsMap) | 1188         if (subscription.url in subscriptionsMap) | 
| 1129           updateSubscription(subscription); | 1189           updateSubscription(subscription); | 
| 1130         else | 1190         else | 
| 1131           addSubscription(subscription); | 1191           addSubscription(subscription); | 
| 1132 | 1192 | 
|  | 1193         if (isAcceptableAds(subscription.url)) | 
|  | 1194           setAcceptableAds(); | 
|  | 1195 | 
| 1133         collections.filterLists.addItem(subscription); | 1196         collections.filterLists.addItem(subscription); | 
| 1134         break; | 1197         break; | 
| 1135       case "removed": | 1198       case "removed": | 
| 1136         if (subscription.url == acceptableAdsUrl || subscription.recommended) | 1199         if (subscription.recommended) | 
| 1137         { | 1200         { | 
| 1138           subscription.disabled = true; | 1201           subscription.disabled = true; | 
| 1139           onSubscriptionMessage("disabled", subscription); | 1202           onSubscriptionMessage("disabled", subscription); | 
| 1140         } | 1203         } | 
| 1141         else | 1204         else | 
| 1142         { | 1205         { | 
| 1143           collections.custom.removeItem(subscription); |  | 
| 1144           delete subscriptionsMap[subscription.url]; | 1206           delete subscriptionsMap[subscription.url]; | 
|  | 1207           if (isAcceptableAds(subscription.url)) | 
|  | 1208           { | 
|  | 1209             setAcceptableAds(); | 
|  | 1210           } | 
|  | 1211           else | 
|  | 1212           { | 
|  | 1213             collections.custom.removeItem(subscription); | 
|  | 1214           } | 
| 1145         } | 1215         } | 
| 1146         collections.filterLists.removeItem(subscription); | 1216         collections.filterLists.removeItem(subscription); | 
| 1147         break; | 1217         break; | 
| 1148     } | 1218     } | 
| 1149 | 1219 | 
| 1150     updateShareLink(); | 1220     updateShareLink(); | 
| 1151   } | 1221   } | 
| 1152 | 1222 | 
| 1153   function hidePref(key, value) | 1223   function hidePref(key, value) | 
| 1154   { | 1224   { | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1225       { | 1295       { | 
| 1226         // Hide the share tab if a script on the share page would be blocked | 1296         // Hide the share tab if a script on the share page would be blocked | 
| 1227         E("tab-share").hidden = isAnyBlocked; | 1297         E("tab-share").hidden = isAnyBlocked; | 
| 1228       } | 1298       } | 
| 1229     } | 1299     } | 
| 1230 | 1300 | 
| 1231     for (let sharedResource of shareResources) | 1301     for (let sharedResource of shareResources) | 
| 1232       checkShareResource(sharedResource, onResult); | 1302       checkShareResource(sharedResource, onResult); | 
| 1233   } | 1303   } | 
| 1234 | 1304 | 
| 1235   function getMessages(id) |  | 
| 1236   { |  | 
| 1237     let messages = []; |  | 
| 1238     for (let i = 1; true; i++) |  | 
| 1239     { |  | 
| 1240       let message = ext.i18n.getMessage(id + "_" + i); |  | 
| 1241       if (!message) |  | 
| 1242         break; |  | 
| 1243 |  | 
| 1244       messages.push(message); |  | 
| 1245     } |  | 
| 1246     return messages; |  | 
| 1247   } |  | 
| 1248 |  | 
| 1249   function updateTooltips() | 1305   function updateTooltips() | 
| 1250   { | 1306   { | 
| 1251     let anchors = document.querySelectorAll(":not(.tooltip) > [data-tooltip]"); | 1307     let anchors = document.querySelectorAll(":not(.tooltip) > [data-tooltip]"); | 
| 1252     for (let anchor of anchors) | 1308     for (let anchor of anchors) | 
| 1253     { | 1309     { | 
| 1254       let id = anchor.getAttribute("data-tooltip"); | 1310       let id = anchor.getAttribute("data-tooltip"); | 
| 1255 | 1311 | 
| 1256       let wrapper = document.createElement("div"); | 1312       let wrapper = document.createElement("div"); | 
| 1257       wrapper.className = "tooltip"; | 1313       wrapper.className = "tooltip"; | 
| 1258       anchor.parentNode.replaceChild(wrapper, anchor); | 1314       anchor.parentNode.replaceChild(wrapper, anchor); | 
| 1259       wrapper.appendChild(anchor); | 1315       wrapper.appendChild(anchor); | 
| 1260 | 1316 | 
| 1261       let topTexts = getMessages(id); |  | 
| 1262       let bottomTexts = getMessages(id + "_notes"); |  | 
| 1263 |  | 
| 1264       // We have to use native tooltips to avoid issues when attaching a tooltip |  | 
| 1265       // to an element in a scrollable list or otherwise it might get cut off |  | 
| 1266       if (anchor.hasAttribute("data-tooltip-native")) |  | 
| 1267       { |  | 
| 1268         let title = topTexts.concat(bottomTexts).join("\n\n"); |  | 
| 1269         anchor.setAttribute("title", title); |  | 
| 1270         continue; |  | 
| 1271       } |  | 
| 1272 |  | 
| 1273       let tooltip = document.createElement("div"); | 1317       let tooltip = document.createElement("div"); | 
| 1274       tooltip.setAttribute("role", "tooltip"); | 1318       tooltip.setAttribute("role", "tooltip"); | 
| 1275 | 1319 | 
| 1276       let flip = anchor.getAttribute("data-tooltip-flip"); | 1320       let paragraph = document.createElement("p"); | 
| 1277       if (flip) | 1321       paragraph.textContent = getMessage(id); | 
| 1278         tooltip.className = "flip-" + flip; | 1322       tooltip.appendChild(paragraph); | 
| 1279 |  | 
| 1280       let imageSource = anchor.getAttribute("data-tooltip-image"); |  | 
| 1281       if (imageSource) |  | 
| 1282       { |  | 
| 1283         let image = document.createElement("img"); |  | 
| 1284         image.src = imageSource; |  | 
| 1285         image.alt = ""; |  | 
| 1286         tooltip.appendChild(image); |  | 
| 1287       } |  | 
| 1288 |  | 
| 1289       for (let topText of topTexts) |  | 
| 1290       { |  | 
| 1291         let paragraph = document.createElement("p"); |  | 
| 1292         paragraph.innerHTML = topText; |  | 
| 1293         tooltip.appendChild(paragraph); |  | 
| 1294       } |  | 
| 1295       if (bottomTexts.length > 0) |  | 
| 1296       { |  | 
| 1297         let notes = document.createElement("div"); |  | 
| 1298         notes.className = "notes"; |  | 
| 1299         for (let bottomText of bottomTexts) |  | 
| 1300         { |  | 
| 1301           let paragraph = document.createElement("p"); |  | 
| 1302           paragraph.innerHTML = bottomText; |  | 
| 1303           notes.appendChild(paragraph); |  | 
| 1304         } |  | 
| 1305         tooltip.appendChild(notes); |  | 
| 1306       } |  | 
| 1307 | 1323 | 
| 1308       wrapper.appendChild(tooltip); | 1324       wrapper.appendChild(tooltip); | 
| 1309     } | 1325     } | 
| 1310   } | 1326   } | 
| 1311 | 1327 | 
| 1312   ext.onMessage.addListener((message) => | 1328   ext.onMessage.addListener((message) => | 
| 1313   { | 1329   { | 
| 1314     switch (message.type) | 1330     switch (message.type) | 
| 1315     { | 1331     { | 
| 1316       case "app.respond": | 1332       case "app.respond": | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1355   }); | 1371   }); | 
| 1356   ext.backgroundPage.sendMessage({ | 1372   ext.backgroundPage.sendMessage({ | 
| 1357     type: "subscriptions.listen", | 1373     type: "subscriptions.listen", | 
| 1358     filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 1374     filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 
| 1359              "title", "downloadStatus", "downloading"] | 1375              "title", "downloadStatus", "downloading"] | 
| 1360   }); | 1376   }); | 
| 1361 | 1377 | 
| 1362   window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1378   window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 
| 1363   window.addEventListener("hashchange", onHashChange, false); | 1379   window.addEventListener("hashchange", onHashChange, false); | 
| 1364 } | 1380 } | 
| OLD | NEW | 
|---|