| LEFT | RIGHT | 
|---|
| 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-2016 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 "use strict"; | 18 "use strict"; | 
| 19 | 19 | 
| 20 (function() | 20 (function() | 
| 21 { | 21 { | 
| 22   var subscriptionsMap = Object.create(null); | 22   var subscriptionsMap = Object.create(null); | 
| 23   var recommendationsMap = Object.create(null); | 23   var recommendationsMap = Object.create(null); | 
| 24   var filtersMap = Object.create(null); | 24   var filtersMap = Object.create(null); | 
| 25   var collections = Object.create(null); | 25   var collections = Object.create(null); | 
| 26   var maxLabelId = 0; | 26   var maxLabelId = 0; | 
|  | 27   var getMessage = ext.i18n.getMessage; | 
|  | 28   var filterErrors = | 
|  | 29   { | 
|  | 30     "synchronize_invalid_url": "options_filterList_lastDownload_invalidURL", | 
|  | 31     "synchronize_connection_error": "options_filterList_lastDownload_connectionE
      rror", | 
|  | 32     "synchronize_invalid_data": "options_filterList_lastDownload_invalidData", | 
|  | 33     "synchronize_checksum_mismatch": "options_filterList_lastDownload_checksumMi
      smatch" | 
|  | 34   }; | 
| 27 | 35 | 
| 28   function Collection(details) | 36   function Collection(details) | 
| 29   { | 37   { | 
| 30     this.details = details; | 38     this.details = details; | 
| 31     this.items = []; | 39     this.items = []; | 
| 32   } | 40   } | 
| 33 | 41 | 
| 34   Collection.prototype._setEmpty = function(table, text) | 42   Collection.prototype._setEmpty = function(table, text) | 
| 35   { | 43   { | 
| 36     var placeholder = table.querySelector(".empty-placeholder"); | 44     var placeholder = table.querySelector(".empty-placeholder"); | 
| 37     if (text && !placeholder) | 45     if (text && !placeholder) | 
| 38     { | 46     { | 
| 39       placeholder = document.createElement("li"); | 47       placeholder = document.createElement("li"); | 
| 40       placeholder.className = "empty-placeholder"; | 48       placeholder.className = "empty-placeholder"; | 
| 41       placeholder.textContent = ext.i18n.getMessage(text); | 49       placeholder.textContent = getMessage(text); | 
| 42       table.appendChild(placeholder); | 50       table.appendChild(placeholder); | 
| 43     } | 51     } | 
| 44     else if (placeholder) | 52     else if (placeholder) | 
| 45       table.removeChild(placeholder); | 53       table.removeChild(placeholder); | 
| 46   } | 54   } | 
| 47 | 55 | 
| 48   Collection.prototype._createElementQuery = function(item) | 56   Collection.prototype._createElementQuery = function(item) | 
| 49   { | 57   { | 
| 50     var access = (item.url || item.text).replace(/'/g, "\\'"); | 58     var access = (item.url || item.text).replace(/'/g, "\\'"); | 
| 51     return function(container) | 59     return function(container) | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 145   Collection.prototype.updateItem = function(item) | 153   Collection.prototype.updateItem = function(item) | 
| 146   { | 154   { | 
| 147     var access = (item.url || item.text).replace(/'/g, "\\'"); | 155     var access = (item.url || item.text).replace(/'/g, "\\'"); | 
| 148     for (var i = 0; i < this.details.length; i++) | 156     for (var i = 0; i < this.details.length; i++) | 
| 149     { | 157     { | 
| 150       var table = E(this.details[i].id); | 158       var table = E(this.details[i].id); | 
| 151       var element = table.querySelector("[data-access='" + access + "']"); | 159       var element = table.querySelector("[data-access='" + access + "']"); | 
| 152       if (!element) | 160       if (!element) | 
| 153         continue; | 161         continue; | 
| 154 | 162 | 
| 155       var text = item.title || item.url || item.text; | 163       var title = item.title || item.url || item.text; | 
| 156       element.querySelector(".display").textContent = text; | 164       element.querySelector(".display").textContent = title; | 
| 157       if (text) | 165       if (title) | 
| 158         element.setAttribute("data-search", text.toLowerCase()); | 166         element.setAttribute("data-search", title.toLowerCase()); | 
| 159       var control = element.querySelector(".control[role='checkbox']"); | 167       var control = element.querySelector(".control[role='checkbox']"); | 
| 160       if (control) | 168       if (control) | 
| 161         control.setAttribute("aria-checked", item.disabled == false); | 169         control.setAttribute("aria-checked", item.disabled == false); | 
| 162 | 170 | 
|  | 171       var downloadStatus = item.downloadStatus; | 
| 163       var dateElement = element.querySelector(".date"); | 172       var dateElement = element.querySelector(".date"); | 
| 164       var timeElement = element.querySelector(".time"); | 173       var timeElement = element.querySelector(".time"); | 
| 165       if(dateElement && timeElement) | 174       if(dateElement && timeElement) | 
| 166       { | 175       { | 
| 167         if (item.downloadStatus && | 176         var message = element.querySelector(".message"); | 
| 168             item.downloadStatus != "synchronize_ok") | 177         ext.backgroundPage.sendMessage( | 
| 169         { | 178         { | 
| 170           var map = | 179           type: "subscriptions.isDownloading", | 
| 171           { | 180           url: item.url | 
| 172             "synchronize_invalid_url": "options_subscription_lastDownload_invali
      dURL", | 181         }, | 
| 173             "synchronize_connection_error": "options_subscription_lastDownload_c
      onnectionError", | 182         function(isDownloading) | 
| 174             "synchronize_invalid_data": "options_subscription_lastDownload_inval
      idData", | 183         { | 
| 175             "synchronize_checksum_mismatch": "options_subscription_lastDownload_
      checksumMismatch" | 184           if (isDownloading) | 
| 176           }; | 185           { | 
| 177           if (item.downloadStatus in map) | 186             var text = getMessage("options_filterList_lastDownload_inProgress"); | 
| 178             timeElement.textContent = ext.i18n.getMessage(map[item.downloadStatu
      s]); | 187             message.textContent = text; | 
| 179           else | 188             element.classList.add("show-message"); | 
| 180             timeElement.textContent = item.downloadStatus; | 189           } | 
| 181         } | 190           else if (downloadStatus && downloadStatus != "synchronize_ok") | 
| 182         else if (item.lastDownload > 0) | 191           { | 
| 183         { | 192             if (downloadStatus in filterErrors) | 
| 184           var dateTime = i18n_formatDateTime(item.lastDownload * 1000); | 193               message.textContent = getMessage(filterErrors[downloadStatus]); | 
| 185           dateElement.textContent = dateTime[0]; | 194             else | 
| 186           timeElement.textContent = dateTime[1]; | 195               message.textContent = item.downloadStatus; | 
| 187         } | 196             element.classList.add("show-message"); | 
|  | 197           } | 
|  | 198           else if (item.lastDownload > 0) | 
|  | 199           { | 
|  | 200             var dateTime = i18n_formatDateTime(item.lastDownload * 1000); | 
|  | 201             dateElement.textContent = dateTime[0]; | 
|  | 202             timeElement.textContent = dateTime[1]; | 
|  | 203             element.classList.remove("show-message"); | 
|  | 204           } | 
|  | 205         }); | 
| 188       } | 206       } | 
| 189       var websiteElement = element.querySelector(".context-menu .website"); | 207       var websiteElement = element.querySelector(".context-menu .website"); | 
| 190       var sourceElement = element.querySelector(".context-menu .source"); | 208       var sourceElement = element.querySelector(".context-menu .source"); | 
| 191       if (websiteElement && item.homepage) | 209       if (websiteElement && item.homepage) | 
| 192         websiteElement.setAttribute("href", item.homepage); | 210         websiteElement.setAttribute("href", item.homepage); | 
| 193       if (sourceElement) | 211       if (sourceElement) | 
| 194         sourceElement.setAttribute("href", item.url); | 212         sourceElement.setAttribute("href", item.url); | 
| 195     } | 213     } | 
| 196   }; | 214   }; | 
| 197 | 215 | 
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 368     { | 386     { | 
| 369       ["disabled", "lastDownload"].forEach(function(property) | 387       ["disabled", "lastDownload"].forEach(function(property) | 
| 370       { | 388       { | 
| 371         subscription["$" + property] = subscription[property]; | 389         subscription["$" + property] = subscription[property]; | 
| 372         Object.defineProperty(subscription, property, | 390         Object.defineProperty(subscription, property, | 
| 373         { | 391         { | 
| 374           get: function() | 392           get: function() | 
| 375           { | 393           { | 
| 376             return this["$" + property]; | 394             return this["$" + property]; | 
| 377           }, | 395           }, | 
| 378           set: function(value) | 396           set: function(newValue) | 
| 379           { | 397           { | 
| 380             this["$" + property] = value; | 398             var oldValue = this["$" + property]; | 
| 381             var change = Object.create(null); | 399             if (oldValue != newValue) | 
| 382             change.name = property; | 400             { | 
| 383             onObjectChanged([change]); | 401               this["$" + property] = newValue; | 
|  | 402               var change = Object.create(null); | 
|  | 403               change.name = property; | 
|  | 404               onObjectChanged([change]); | 
|  | 405             } | 
| 384           } | 406           } | 
| 385         }); | 407         }); | 
| 386       }); | 408       }); | 
| 387     } | 409     } | 
| 388     else | 410     else | 
| 389     { | 411     { | 
| 390       Object.observe(subscription, onObjectChanged); | 412       Object.observe(subscription, onObjectChanged); | 
| 391     } | 413     } | 
| 392   } | 414   } | 
| 393 | 415 | 
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 462           subscription.url = element.getAttribute("url"); | 484           subscription.url = element.getAttribute("url"); | 
| 463           subscription.disabled = null; | 485           subscription.disabled = null; | 
| 464           subscription.downloadStatus = null; | 486           subscription.downloadStatus = null; | 
| 465           subscription.homepage = null; | 487           subscription.homepage = null; | 
| 466           var recommendation = Object.create(null); | 488           var recommendation = Object.create(null); | 
| 467           recommendation.type = element.getAttribute("type"); | 489           recommendation.type = element.getAttribute("type"); | 
| 468           var prefix = element.getAttribute("prefixes"); | 490           var prefix = element.getAttribute("prefixes"); | 
| 469           if (prefix) | 491           if (prefix) | 
| 470           { | 492           { | 
| 471             prefix = prefix.replace(/\W/g, "_"); | 493             prefix = prefix.replace(/\W/g, "_"); | 
| 472             subscription.title = ext.i18n.getMessage("options_language_" + prefi
      x); | 494             subscription.title = getMessage("options_language_" + prefix); | 
| 473           } | 495           } | 
| 474           else | 496           else | 
| 475           { | 497           { | 
| 476             var type = recommendation.type.replace(/\W/g, "_"); | 498             var type = recommendation.type.replace(/\W/g, "_"); | 
| 477             subscription.title = ext.i18n.getMessage("common_feature_" + type + 
      "_title"); | 499             subscription.title = getMessage("common_feature_" + type + "_title")
      ; | 
| 478           } | 500           } | 
| 479 | 501 | 
| 480           recommendationsMap[subscription.url] = recommendation; | 502           recommendationsMap[subscription.url] = recommendation; | 
| 481           updateSubscription(subscription); | 503           updateSubscription(subscription); | 
| 482         } | 504         } | 
| 483       }); | 505       }); | 
| 484   } | 506   } | 
| 485 | 507 | 
| 486   function findParentData(element, dataName, returnElement) | 508   function findParentData(element, dataName, returnElement) | 
| 487   { | 509   { | 
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 567             element.getAttribute("data-tab")); | 589             element.getAttribute("data-tab")); | 
| 568           break; | 590           break; | 
| 569         case "update-all-subscriptions": | 591         case "update-all-subscriptions": | 
| 570           ext.backgroundPage.sendMessage( | 592           ext.backgroundPage.sendMessage( | 
| 571           { | 593           { | 
| 572             type: "subscriptions.update" | 594             type: "subscriptions.update" | 
| 573           }); | 595           }); | 
| 574           break; | 596           break; | 
| 575         case "open-context-menu": | 597         case "open-context-menu": | 
| 576           var listItem = findParentData(element, "access", true); | 598           var listItem = findParentData(element, "access", true); | 
| 577           listItem.classList.add("show-context-menu"); | 599           if (listItem != context) | 
| 578           break; | 600             listItem.classList.add("show-context-menu"); | 
| 579         case "update-now": | 601           break; | 
|  | 602         case "update-subscription": | 
| 580           ext.backgroundPage.sendMessage( | 603           ext.backgroundPage.sendMessage( | 
| 581           { | 604           { | 
| 582             type: "subscriptions.update", | 605             type: "subscriptions.update", | 
| 583             url: findParentData(element, "access", false) | 606             url: findParentData(element, "access", false) | 
| 584           }); | 607           }); | 
| 585           break; | 608           break; | 
| 586         case "remove-subscription": | 609         case "remove-subscription": | 
| 587           ext.backgroundPage.sendMessage( | 610           ext.backgroundPage.sendMessage( | 
| 588           { | 611           { | 
| 589             type: "subscriptions.remove", | 612             type: "subscriptions.remove", | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 636 | 659 | 
| 637     getDocLink("contribute", function(link) | 660     getDocLink("contribute", function(link) | 
| 638     { | 661     { | 
| 639       document.querySelector("#tab-contribute a").setAttribute("href", link); | 662       document.querySelector("#tab-contribute a").setAttribute("href", link); | 
| 640     }); | 663     }); | 
| 641 | 664 | 
| 642     updateShareLink(); | 665     updateShareLink(); | 
| 643 | 666 | 
| 644     // Initialize interactive UI elements | 667     // Initialize interactive UI elements | 
| 645     document.body.addEventListener("click", onClick, false); | 668     document.body.addEventListener("click", onClick, false); | 
| 646     var placeholderValue  = ext.i18n.getMessage("options_dialog_language_find"); | 669     var placeholderValue  = getMessage("options_dialog_language_find"); | 
| 647     E("find-language").setAttribute("placeholder", placeholderValue); | 670     E("find-language").setAttribute("placeholder", placeholderValue); | 
| 648     E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); | 671     E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); | 
| 649     E("whitelisting-textbox").addEventListener("keypress", function(e) | 672     E("whitelisting-textbox").addEventListener("keypress", function(e) | 
| 650     { | 673     { | 
| 651       if (getKey(e) == "Enter") | 674       if (getKey(e) == "Enter") | 
| 652         addWhitelistedDomain(); | 675         addWhitelistedDomain(); | 
| 653     }, false); | 676     }, false); | 
| 654 | 677 | 
| 655     // Advanced tab | 678     // Advanced tab | 
| 656     var filterTextbox = document.querySelector("#custom-filters-add input"); | 679     var filterTextbox = document.querySelector("#custom-filters-add input"); | 
| 657     placeholderValue = ext.i18n.getMessage("options_customFilters_textbox_placeh
      older"); | 680     placeholderValue = getMessage("options_customFilters_textbox_placeholder"); | 
| 658     filterTextbox.setAttribute("placeholder", placeholderValue); | 681     filterTextbox.setAttribute("placeholder", placeholderValue); | 
| 659     function addCustomFilters() | 682     function addCustomFilters() | 
| 660     { | 683     { | 
| 661       var filterText = filterTextbox.value; | 684       var filterText = filterTextbox.value; | 
| 662       ext.backgroundPage.sendMessage( | 685       ext.backgroundPage.sendMessage( | 
| 663       { | 686       { | 
| 664         type: "filters.add", | 687         type: "filters.add", | 
| 665         text: filterText | 688         text: filterText | 
| 666       }); | 689       }); | 
| 667       filterTextbox.value = ""; | 690       filterTextbox.value = ""; | 
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 755             updateFilter(filters[i]); | 778             updateFilter(filters[i]); | 
| 756         }); | 779         }); | 
| 757       } | 780       } | 
| 758     }); | 781     }); | 
| 759     loadRecommendations(); | 782     loadRecommendations(); | 
| 760     getAcceptableAdsURL(function(acceptableAdsUrl) | 783     getAcceptableAdsURL(function(acceptableAdsUrl) | 
| 761     { | 784     { | 
| 762       var subscription = Object.create(null); | 785       var subscription = Object.create(null); | 
| 763       subscription.url = acceptableAdsUrl; | 786       subscription.url = acceptableAdsUrl; | 
| 764       subscription.disabled = true; | 787       subscription.disabled = true; | 
| 765       subscription.title = ext.i18n.getMessage("options_acceptableAds_descriptio
      n"); | 788       subscription.title = getMessage("options_acceptableAds_description"); | 
| 766       updateSubscription(subscription); | 789       updateSubscription(subscription); | 
| 767 | 790 | 
| 768       // Load user subscriptions | 791       // Load user subscriptions | 
| 769       ext.backgroundPage.sendMessage( | 792       ext.backgroundPage.sendMessage( | 
| 770       { | 793       { | 
| 771         type: "subscriptions.get", | 794         type: "subscriptions.get", | 
| 772         downloadable: true | 795         downloadable: true | 
| 773       }, | 796       }, | 
| 774       function(subscriptions) | 797       function(subscriptions) | 
| 775       { | 798       { | 
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 995     filter: ["added", "loaded", "removed"] | 1018     filter: ["added", "loaded", "removed"] | 
| 996   }); | 1019   }); | 
| 997   ext.backgroundPage.sendMessage( | 1020   ext.backgroundPage.sendMessage( | 
| 998   { | 1021   { | 
| 999     type: "subscriptions.listen", | 1022     type: "subscriptions.listen", | 
| 1000     filter: ["added", "disabled", "homepage", "lastDownload", "removed", "title"
      ] | 1023     filter: ["added", "disabled", "homepage", "lastDownload", "removed", "title"
      ] | 
| 1001   }); | 1024   }); | 
| 1002 | 1025 | 
| 1003   window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1026   window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 
| 1004 })(); | 1027 })(); | 
| LEFT | RIGHT | 
|---|