| Left: | ||
| Right: |
| 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-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/>. |
|
Sebastian Noack
2016/04/03 15:05:14
This rewrite is a good opportunity to turn on stri
kzar
2016/04/03 15:50:19
Done.
| |
| 16 */ | 16 */ |
| 17 | 17 |
| 18 var backgroundPage = ext.backgroundPage.getWindow(); | 18 /** |
| 19 var require = backgroundPage.require; | 19 * Creates a wrapping function used to conveniently send a type of message. |
| 20 * | |
| 21 * @param {Object} baseMessage The part of the message that's always sent | |
| 22 * @param {..string} paramKeys Any message keys that have dynamic values. The | |
| 23 * returned function will take the corresponding | |
| 24 * values as arguments. | |
| 25 * @return The generated messaging function, optionally taking any values as | |
| 26 * specified by the paramKeys and finally an optional callback. | |
| 27 * (Although the value arguments are optional their index must be | |
| 28 * maintained. E.g. if you omit the first value you must omit the | |
| 29 * second too.) | |
| 30 */ | |
| 31 function wrapper(baseMessage /* , [paramKeys] */) | |
| 32 { | |
| 33 var paramKeys = []; | |
| 34 for (var i = 1; i < arguments.length; i++) | |
| 35 paramKeys.push(arguments[i]); | |
| 20 | 36 |
| 21 with(require("filterClasses")) | 37 return function(/* [paramValues], callback */) |
| 22 { | 38 { |
| 23 this.Filter = Filter; | 39 var message = Object.create(null); |
| 24 this.WhitelistFilter = WhitelistFilter; | 40 for (var key in baseMessage) |
| 41 if (baseMessage.hasOwnProperty(key)) | |
| 42 message[key] = baseMessage[key]; | |
| 43 | |
| 44 var paramValues = []; | |
| 45 var callback; | |
| 46 | |
| 47 if (arguments.length > 0) | |
| 48 { | |
| 49 var lastArg = arguments[arguments.length - 1]; | |
| 50 if (typeof lastArg == "function") | |
| 51 callback = lastArg; | |
| 52 | |
| 53 for (var i = 0; i < arguments.length - (callback ? 1 : 0); i++) | |
| 54 message[paramKeys[i]] = arguments[i]; | |
| 55 } | |
| 56 | |
| 57 ext.backgroundPage.sendMessage(message, callback); | |
|
kzar
2016/04/03 10:55:06
(I considered having this function return a promis
| |
| 58 }; | |
| 25 } | 59 } |
| 26 with(require("subscriptionClasses")) | |
| 27 { | |
| 28 this.Subscription = Subscription; | |
| 29 this.SpecialSubscription = SpecialSubscription; | |
| 30 this.DownloadableSubscription = DownloadableSubscription; | |
| 31 } | |
| 32 with(require("filterValidation")) | |
| 33 { | |
| 34 this.parseFilter = parseFilter; | |
| 35 this.parseFilters = parseFilters; | |
| 36 } | |
| 37 var FilterStorage = require("filterStorage").FilterStorage; | |
| 38 var FilterNotifier = require("filterNotifier").FilterNotifier; | |
| 39 var Prefs = require("prefs").Prefs; | |
| 40 var Synchronizer = require("synchronizer").Synchronizer; | |
| 41 var Utils = require("utils").Utils; | |
| 42 var NotificationStorage = require("notification").Notification; | |
| 43 var info = require("info"); | |
| 44 | 60 |
| 45 // Loads options from localStorage and sets UI elements accordingly | 61 var getDocLink = wrapper({type: "app.get", what: "doclink"}, "link"); |
|
Sebastian Noack
2016/04/03 15:05:14
This is redundant with getDocLink() from common.js
kzar
2016/04/03 15:50:19
I don't think adblockplusui/common.js is included
Sebastian Noack
2016/04/03 17:18:03
Given that common.js is already used by the first
kzar
2016/04/05 11:10:14
I think I prefer to leave this as it is.
| |
| 62 var getInfo = wrapper({type: "app.get"}, "what"); | |
| 63 var getPref = wrapper({type: "prefs.get"}, "key"); | |
| 64 var togglePref = wrapper({type: "prefs.toggle"}, "key"); | |
| 65 var getSubscriptions = wrapper({type: "subscriptions.get"}, | |
| 66 "downloadable", "special"); | |
| 67 var removeSubscription = wrapper({type: "subscriptions.remove"}, "url"); | |
| 68 var addSubscription = wrapper({type: "subscriptions.add"}, | |
| 69 "url", "title", "homepage"); | |
| 70 var toggleSubscription = wrapper({type: "subscriptions.toggle"}, | |
| 71 "url", "keepInstalled"); | |
| 72 var updateSubscription = wrapper({type: "subscriptions.update"}, "url"); | |
| 73 var isSubscriptionDownloading = wrapper({type: "subscriptions.isDownloading"}, | |
| 74 "url"); | |
| 75 var importRawFilters = wrapper({type: "filters.importRaw"}, "text"); | |
| 76 var addFilter = wrapper({type: "filters.add"}, "text"); | |
| 77 var getFilters = wrapper({type: "filters.get"}, "subscriptionUrl"); | |
| 78 var removeFilter = wrapper({type: "filters.remove"}, "text"); | |
| 79 | |
| 80 var i18n = ext.i18n; | |
| 81 var whitelistedDomainRegexp = /^@@\|\|([^\/:]+)\^\$document$/; | |
| 82 var delayedSubscriptionSelection = null; | |
| 83 | |
| 84 // Loads options and sets UI elements accordingly | |
| 46 function loadOptions() | 85 function loadOptions() |
| 47 { | 86 { |
| 48 // Set page title to i18n version of "Adblock Plus Options" | 87 // Set page title to i18n version of "Adblock Plus Options" |
| 49 document.title = i18n.getMessage("options"); | 88 document.title = i18n.getMessage("options"); |
| 50 | 89 |
| 51 // Set links | 90 // Set links |
| 52 $("#acceptableAdsLink").attr("href", Prefs.subscriptions_exceptionsurl); | 91 getPref("subscriptions_exceptionsurl", function (url) |
| 53 $("#acceptableAdsDocs").attr("href", Utils.getDocLink("acceptable_ads")); | 92 { |
| 54 setLinks("filter-must-follow-syntax", Utils.getDocLink("filterdoc")); | 93 $("#acceptableAdsLink").attr("href", url); |
| 55 setLinks("found-a-bug", Utils.getDocLink(info.application + "_support")); | 94 }); |
| 95 getDocLink("acceptable_ads", function (url) | |
| 96 { | |
| 97 $("#acceptableAdsDocs").attr("href", url); | |
| 98 }); | |
| 99 getDocLink("filterdoc", function (url) | |
| 100 { | |
| 101 setLinks("filter-must-follow-syntax", url); | |
| 102 }); | |
| 103 getInfo("application", function (application) | |
| 104 { | |
| 105 getInfo("platform", function (platform) | |
| 106 { | |
| 107 if (platform == "chromium" && application != "opera") | |
| 108 application = "chrome"; | |
| 109 | |
| 110 getDocLink(application + "_support", function (url) | |
| 111 { | |
| 112 setLinks("found-a-bug", url); | |
| 113 }); | |
| 114 }); | |
| 115 }); | |
| 56 | 116 |
| 57 // Add event listeners | 117 // Add event listeners |
| 58 window.addEventListener("unload", unloadOptions, false); | |
| 59 $("#updateFilterLists").click(updateFilterLists); | 118 $("#updateFilterLists").click(updateFilterLists); |
| 60 $("#startSubscriptionSelection").click(startSubscriptionSelection); | 119 $("#startSubscriptionSelection").click(startSubscriptionSelection); |
| 61 $("#subscriptionSelector").change(updateSubscriptionSelection); | 120 $("#subscriptionSelector").change(updateSubscriptionSelection); |
| 62 $("#addSubscription").click(addSubscription); | 121 $("#addSubscription").click(addSubscriptionClicked); |
| 63 $("#acceptableAds").click(allowAcceptableAds); | 122 $("#acceptableAds").click(toggleAcceptableAds); |
| 64 $("#whitelistForm").submit(addWhitelistDomain); | 123 $("#whitelistForm").submit(addWhitelistDomain); |
| 65 $("#removeWhitelist").click(removeSelectedExcludedDomain); | 124 $("#removeWhitelist").click(removeSelectedExcludedDomain); |
| 66 $("#customFilterForm").submit(addTypedFilter); | 125 $("#customFilterForm").submit(addTypedFilter); |
| 67 $("#removeCustomFilter").click(removeSelectedFilters); | 126 $("#removeCustomFilter").click(removeSelectedFilters); |
| 68 $("#rawFiltersButton").click(toggleFiltersInRawFormat); | 127 $("#rawFiltersButton").click(toggleFiltersInRawFormat); |
| 69 $("#importRawFilters").click(importRawFiltersText); | 128 $("#importRawFilters").click(importRawFiltersText); |
| 70 | 129 |
| 71 FilterNotifier.on("load", reloadFilters); | |
| 72 FilterNotifier.on("subscription.title", onSubscriptionChange); | |
| 73 FilterNotifier.on("subscription.disabled", onSubscriptionChange); | |
| 74 FilterNotifier.on("subscription.homepage", onSubscriptionChange); | |
| 75 FilterNotifier.on("subscription.lastDownload", onSubscriptionChange); | |
| 76 FilterNotifier.on("subscription.downloadStatus", onSubscriptionChange); | |
| 77 FilterNotifier.on("subscription.added", onSubscriptionAdded); | |
| 78 FilterNotifier.on("subscription.removed", onSubscriptionRemoved); | |
| 79 FilterNotifier.on("filter.added", onFilterAdded); | |
| 80 FilterNotifier.on("filter.removed", onFilterRemoved); | |
| 81 | |
| 82 // Display jQuery UI elements | 130 // Display jQuery UI elements |
| 83 $("#tabs").tabs(); | 131 $("#tabs").tabs(); |
| 84 $("button").button(); | 132 $("button").button(); |
| 85 $(".refreshButton").button("option", "icons", {primary: "ui-icon-refresh"}); | 133 $(".refreshButton").button("option", "icons", {primary: "ui-icon-refresh"}); |
| 86 $(".addButton").button("option", "icons", {primary: "ui-icon-plus"}); | 134 $(".addButton").button("option", "icons", {primary: "ui-icon-plus"}); |
| 87 $(".removeButton").button("option", "icons", {primary: "ui-icon-minus"}); | 135 $(".removeButton").button("option", "icons", {primary: "ui-icon-minus"}); |
| 88 | 136 |
| 89 // Popuplate option checkboxes | 137 // Popuplate option checkboxes |
| 90 initCheckbox("shouldShowBlockElementMenu"); | 138 initCheckbox("shouldShowBlockElementMenu"); |
| 91 initCheckbox("show_devtools_panel"); | 139 initCheckbox("show_devtools_panel"); |
| 92 initCheckbox("shouldShowNotifications", { | 140 initCheckbox("shouldShowNotifications", { |
| 93 get: function() | 141 key: "notifications_ignoredcategories", |
| 142 get: function(ignoredcategories) | |
| 94 { | 143 { |
| 95 return Prefs.notifications_ignoredcategories.indexOf("*") == -1; | 144 return ignoredcategories.indexOf("*") == -1; |
| 96 }, | |
| 97 toggle: function() | |
| 98 { | |
| 99 NotificationStorage.toggleIgnoreCategory("*"); | |
| 100 return this.get(); | |
| 101 } | 145 } |
| 102 }); | 146 }); |
| 103 | 147 |
| 104 if (info.platform != "chromium") | 148 getInfo("platform", function (platform) |
|
Sebastian Noack
2016/04/03 15:05:14
Please use app.get[features] like the new options
kzar
2016/04/03 15:50:19
Done.
| |
| 105 document.getElementById("showDevtoolsPanelContainer").hidden = true; | 149 { |
| 106 if (!Prefs.notifications_showui) | 150 if (platform != "chromium") |
| 107 document.getElementById("shouldShowNotificationsContainer").hidden = true; | 151 document.getElementById("showDevtoolsPanelContainer").hidden = true; |
| 152 }); | |
| 153 getPref("notifications_showui", function (notifications_showui) | |
| 154 { | |
| 155 if (!notifications_showui) | |
| 156 document.getElementById("shouldShowNotificationsContainer").hidden = true; | |
| 157 }); | |
| 108 | 158 |
| 109 ext.onMessage.addListener(onMessage); | 159 // Register listeners in the background message responder |
| 110 ext.backgroundPage.sendMessage({ | 160 ext.backgroundPage.sendMessage({ |
| 111 type: "app.listen", | 161 type: "app.listen", |
| 112 filter: ["addSubscription"] | 162 filter: ["addSubscription"] |
| 113 }); | 163 }); |
| 164 ext.backgroundPage.sendMessage( | |
| 165 { | |
| 166 type: "filters.listen", | |
| 167 filter: ["added", "loaded", "removed"] | |
| 168 }); | |
| 169 ext.backgroundPage.sendMessage( | |
| 170 { | |
| 171 type: "prefs.listen", | |
| 172 filter: ["notifications_ignoredcategories", "notifications_showui", | |
| 173 "safari_contentblocker", "show_devtools_panel", | |
| 174 "shouldShowBlockElementMenu"] | |
| 175 }); | |
| 176 ext.backgroundPage.sendMessage( | |
| 177 { | |
| 178 type: "subscriptions.listen", | |
| 179 filter: ["added", "disabled", "homepage", "lastDownload", "removed", | |
| 180 "title"] | |
| 181 }); | |
| 114 | 182 |
| 115 // Load recommended subscriptions | 183 // Load recommended subscriptions |
| 116 loadRecommendations(); | 184 loadRecommendations(); |
| 117 | 185 |
| 118 // Show user's filters | 186 // Show user's filters |
| 119 reloadFilters(); | 187 reloadFilters(); |
| 120 } | 188 } |
| 121 $(loadOptions); | 189 $(loadOptions); |
| 122 | 190 |
| 123 function onMessage(msg) | |
| 124 { | |
| 125 if (msg.type == "app.listen") | |
| 126 { | |
| 127 if (msg.action == "addSubscription") | |
| 128 { | |
| 129 var subscription = msg.args[0]; | |
| 130 startSubscriptionSelection(subscription.title, subscription.url); | |
| 131 } | |
| 132 } | |
| 133 else if (msg.type == "focus-section") | |
| 134 { | |
| 135 var tabs = document.getElementsByClassName("ui-tabs-panel"); | |
| 136 for (var i = 0; i < tabs.length; i++) | |
| 137 { | |
| 138 var found = tabs[i].querySelector("[data-section='" + msg.section + "']"); | |
| 139 if (!found) | |
| 140 continue; | |
| 141 | |
| 142 var previous = document.getElementsByClassName("focused"); | |
| 143 if (previous.length > 0) | |
| 144 previous[0].classList.remove("focused"); | |
| 145 | |
| 146 var tab = $("[href='#" + tabs[i].id + "']"); | |
| 147 $("#tabs").tabs("select", tab.parent().index()); | |
| 148 found.classList.add("focused"); | |
| 149 } | |
| 150 } | |
| 151 }; | |
| 152 | |
| 153 // Reloads the displayed subscriptions and filters | 191 // Reloads the displayed subscriptions and filters |
| 154 function reloadFilters() | 192 function reloadFilters() |
| 155 { | 193 { |
| 156 // Load user filter URLs | 194 // Load user filter URLs |
| 157 var container = document.getElementById("filterLists"); | 195 var container = document.getElementById("filterLists"); |
| 158 while (container.lastChild) | 196 while (container.lastChild) |
| 159 container.removeChild(container.lastChild); | 197 container.removeChild(container.lastChild); |
| 160 | 198 |
| 161 var hasAcceptable = false; | 199 getPref("subscriptions_exceptionsurl", function (acceptableAdsUrl) |
| 162 for (var i = 0; i < FilterStorage.subscriptions.length; i++) | |
| 163 { | 200 { |
| 164 var subscription = FilterStorage.subscriptions[i]; | 201 getSubscriptions(true, false, function(subscriptions) |
| 165 if (subscription instanceof SpecialSubscription) | |
| 166 continue; | |
| 167 | |
| 168 if (subscription.url == Prefs.subscriptions_exceptionsurl) | |
| 169 { | 202 { |
| 170 hasAcceptable = true; | 203 for (var i = 0; i < subscriptions.length; i++) |
| 171 continue; | 204 { |
| 172 } | 205 var subscription = subscriptions[i]; |
| 173 | 206 if (subscription.url == acceptableAdsUrl) |
| 174 addSubscriptionEntry(subscription); | 207 $("#acceptableAds").prop("checked", !subscription.disabled); |
| 175 } | 208 else |
| 176 | 209 addSubscriptionEntry(subscription); |
| 177 $("#acceptableAds").prop("checked", hasAcceptable); | 210 } |
| 211 }); | |
| 212 }); | |
| 178 | 213 |
| 179 // User-entered filters | 214 // User-entered filters |
| 180 var userFilters = backgroundPage.getUserFilters(); | 215 getSubscriptions(false, true, function(subscriptions) |
|
Sebastian Noack
2016/04/03 15:05:14
How about removing this function from background.j
kzar
2016/04/03 15:50:19
Done.
| |
| 181 populateList("userFiltersBox", userFilters.filters); | 216 { |
| 182 populateList("excludedDomainsBox", userFilters.exceptions); | 217 clearListBox("userFiltersBox"); |
| 183 } | 218 clearListBox("excludedDomainsBox"); |
| 184 | 219 |
| 185 // Cleans up when the options window is closed | 220 for (var i = 0; i < subscriptions.length; i++) |
| 186 function unloadOptions() | 221 getFilters(subscriptions[i].url, function(filters) |
| 187 { | 222 { |
| 188 FilterNotifier.off("load", reloadFilters); | 223 for (var j = 0; j < filters.length; j++) |
| 189 FilterNotifier.off("subscription.title", onSubscriptionChange); | 224 { |
| 190 FilterNotifier.off("subscription.disabled", onSubscriptionChange); | 225 var filter = filters[j].text; |
| 191 FilterNotifier.off("subscription.homepage", onSubscriptionChange); | 226 if (whitelistedDomainRegexp.test(filter)) |
| 192 FilterNotifier.off("subscription.lastDownload", onSubscriptionChange); | 227 appendToListBox("excludedDomainsBox", RegExp.$1); |
| 193 FilterNotifier.off("subscription.downloadStatus", onSubscriptionChange); | 228 else |
| 194 FilterNotifier.off("subscription.added", onSubscriptionAdded); | 229 appendToListBox("userFiltersBox", filter); |
| 195 FilterNotifier.off("subscription.removed", onSubscriptionRemoved); | 230 } |
| 196 FilterNotifier.off("filter.added", onFilterAdded); | 231 }); |
| 197 FilterNotifier.off("filter.removed", onFilterRemoved); | 232 }); |
| 198 } | 233 } |
| 199 | 234 |
| 200 function initCheckbox(id, descriptor) | 235 function initCheckbox(id, descriptor) |
| 201 { | 236 { |
| 202 var checkbox = document.getElementById(id); | 237 var checkbox = document.getElementById(id); |
| 203 if (descriptor && descriptor.get) | 238 var key = descriptor && descriptor.key || id; |
| 204 checkbox.checked = descriptor.get(); | 239 getPref(key, function (value) |
| 205 else | 240 { |
| 206 checkbox.checked = Prefs[id]; | 241 if (descriptor && descriptor.get) |
| 242 checkbox.checked = descriptor.get(value); | |
| 243 else | |
| 244 checkbox.checked = value; | |
| 245 }); | |
| 207 | 246 |
| 208 checkbox.addEventListener("click", function() | 247 checkbox.addEventListener("click", function() |
| 209 { | 248 { |
| 210 if (descriptor && descriptor.toggle) | 249 if (descriptor && descriptor.toggle) |
| 211 checkbox.checked = descriptor.toggle(); | 250 checkbox.checked = descriptor.toggle(); |
| 212 | 251 togglePref(key); |
| 213 Prefs[id] = checkbox.checked; | |
| 214 }, false); | 252 }, false); |
| 215 } | 253 } |
| 216 | 254 |
| 217 var delayedSubscriptionSelection = null; | |
| 218 | |
| 219 function loadRecommendations() | 255 function loadRecommendations() |
| 220 { | 256 { |
| 221 fetch("subscriptions.xml") | 257 fetch("subscriptions.xml") |
| 222 .then(function(response) | 258 .then(function(response) |
| 223 { | 259 { |
| 224 return response.text(); | 260 return response.text(); |
| 225 }) | 261 }) |
| 226 .then(function(text) | 262 .then(function(text) |
| 227 { | 263 { |
| 228 var selectedIndex = 0; | 264 var selectedIndex = 0; |
| 229 var selectedPrefix = null; | 265 var selectedPrefix = null; |
| 230 var matchCount = 0; | 266 var matchCount = 0; |
| 231 | 267 |
| 232 var list = document.getElementById("subscriptionSelector"); | 268 var list = document.getElementById("subscriptionSelector"); |
| 233 var doc = new DOMParser().parseFromString(text, "application/xml"); | 269 var doc = new DOMParser().parseFromString(text, "application/xml"); |
| 234 var elements = doc.documentElement.getElementsByTagName("subscription"); | 270 var elements = doc.documentElement.getElementsByTagName("subscription"); |
| 235 | 271 |
| 236 for (var i = 0; i < elements.length; i++) | 272 for (var i = 0; i < elements.length; i++) |
| 237 { | 273 { |
| 238 var element = elements[i]; | 274 var element = elements[i]; |
| 239 var option = new Option(); | 275 var option = new Option(); |
| 240 option.text = element.getAttribute("title") + " (" + | 276 option.text = element.getAttribute("title") + " (" + |
| 241 element.getAttribute("specialization") + ")"; | 277 element.getAttribute("specialization") + ")"; |
| 242 option._data = { | 278 option._data = { |
| 243 title: element.getAttribute("title"), | 279 title: element.getAttribute("title"), |
| 244 url: element.getAttribute("url"), | 280 url: element.getAttribute("url"), |
| 245 homepage: element.getAttribute("homepage") | 281 homepage: element.getAttribute("homepage") |
| 246 }; | 282 }; |
| 247 | 283 |
| 248 var prefixes = element.getAttribute("prefixes"); | 284 var prefix = element.getAttribute("prefixes"); |
| 249 var prefix = Utils.checkLocalePrefixMatch(prefixes); | |
| 250 if (prefix) | 285 if (prefix) |
| 251 { | 286 { |
| 287 prefix = prefix.replace(/\W/g, "_"); | |
| 252 option.style.fontWeight = "bold"; | 288 option.style.fontWeight = "bold"; |
| 253 option.style.backgroundColor = "#E0FFE0"; | 289 option.style.backgroundColor = "#E0FFE0"; |
| 254 option.style.color = "#000000"; | 290 option.style.color = "#000000"; |
| 255 if (!selectedPrefix || selectedPrefix.length < prefix.length) | 291 if (!selectedPrefix || selectedPrefix.length < prefix.length) |
| 256 { | 292 { |
| 257 selectedIndex = i; | 293 selectedIndex = i; |
| 258 selectedPrefix = prefix; | 294 selectedPrefix = prefix; |
| 259 matchCount = 1; | 295 matchCount = 1; |
| 260 } | 296 } |
| 261 else if (selectedPrefix && selectedPrefix.length == prefix.length) | 297 else if (selectedPrefix && selectedPrefix.length == prefix.length) |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 var data = list.options[list.selectedIndex]._data; | 354 var data = list.options[list.selectedIndex]._data; |
| 319 if (data) | 355 if (data) |
| 320 $("#customSubscriptionContainer").hide(); | 356 $("#customSubscriptionContainer").hide(); |
| 321 else | 357 else |
| 322 { | 358 { |
| 323 $("#customSubscriptionContainer").show(); | 359 $("#customSubscriptionContainer").show(); |
| 324 $("#customSubscriptionTitle").focus(); | 360 $("#customSubscriptionTitle").focus(); |
| 325 } | 361 } |
| 326 } | 362 } |
| 327 | 363 |
| 328 function addSubscription() | 364 function addSubscriptionClicked() |
| 329 { | 365 { |
| 330 var list = document.getElementById("subscriptionSelector"); | 366 var list = document.getElementById("subscriptionSelector"); |
| 331 var data = list.options[list.selectedIndex]._data; | 367 var data = list.options[list.selectedIndex]._data; |
| 332 if (data) | 368 if (data) |
| 333 doAddSubscription(data.url, data.title, data.homepage); | 369 addSubscription(data.url, data.title, data.homepage); |
| 334 else | 370 else |
| 335 { | 371 { |
| 336 var url = document.getElementById("customSubscriptionLocation").value.trim() ; | 372 var url = document.getElementById("customSubscriptionLocation").value.trim() ; |
| 337 if (!/^https?:/i.test(url)) | 373 if (!/^https?:/i.test(url)) |
| 338 { | 374 { |
| 339 alert(i18n.getMessage("global_subscription_invalid_location")); | 375 alert(i18n.getMessage("global_subscription_invalid_location")); |
| 340 $("#customSubscriptionLocation").focus(); | 376 $("#customSubscriptionLocation").focus(); |
| 341 return; | 377 return; |
| 342 } | 378 } |
| 343 | 379 |
| 344 var title = document.getElementById("customSubscriptionTitle").value.trim(); | 380 var title = document.getElementById("customSubscriptionTitle").value.trim(); |
| 345 if (!title) | 381 if (!title) |
| 346 title = url; | 382 title = url; |
| 347 | 383 |
| 348 doAddSubscription(url, title, null); | 384 addSubscription(url, title, null); |
| 349 } | 385 } |
| 350 | 386 |
| 351 $("#addSubscriptionContainer").hide(); | 387 $("#addSubscriptionContainer").hide(); |
| 352 $("#customSubscriptionContainer").hide(); | 388 $("#customSubscriptionContainer").hide(); |
| 353 $("#addSubscriptionButton").show(); | 389 $("#addSubscriptionButton").show(); |
| 354 } | 390 } |
| 355 | 391 |
| 356 function doAddSubscription(url, title, homepage) | 392 function toggleAcceptableAds() |
| 357 { | 393 { |
| 358 if (url in FilterStorage.knownSubscriptions) | 394 getPref("subscriptions_exceptionsurl", function (url) |
| 359 return; | |
| 360 | |
| 361 var subscription = Subscription.fromURL(url); | |
| 362 if (!subscription) | |
| 363 return; | |
| 364 | |
| 365 subscription.title = title; | |
| 366 if (homepage) | |
| 367 subscription.homepage = homepage; | |
| 368 FilterStorage.addSubscription(subscription); | |
| 369 | |
| 370 if (subscription instanceof DownloadableSubscription && !subscription.lastDown load) | |
| 371 Synchronizer.execute(subscription); | |
| 372 } | |
| 373 | |
| 374 function allowAcceptableAds(event) | |
| 375 { | |
| 376 var subscription = Subscription.fromURL(Prefs.subscriptions_exceptionsurl); | |
| 377 if (!subscription) | |
| 378 return; | |
| 379 | |
| 380 subscription.disabled = false; | |
| 381 subscription.title = "Allow non-intrusive advertising"; | |
| 382 if ($("#acceptableAds").prop("checked")) | |
| 383 { | 395 { |
| 384 FilterStorage.addSubscription(subscription); | 396 toggleSubscription(url, true); |
| 385 if (subscription instanceof DownloadableSubscription && !subscription.lastDo wnload) | 397 }); |
| 386 Synchronizer.execute(subscription); | |
| 387 } | |
| 388 else | |
| 389 FilterStorage.removeSubscription(subscription); | |
| 390 } | 398 } |
| 391 | 399 |
| 392 function findSubscriptionElement(subscription) | 400 function findSubscriptionElement(subscription) |
| 393 { | 401 { |
| 394 var children = document.getElementById("filterLists").childNodes; | 402 var children = document.getElementById("filterLists").childNodes; |
| 395 for (var i = 0; i < children.length; i++) | 403 for (var i = 0; i < children.length; i++) |
| 396 if (children[i]._subscription == subscription) | 404 if (children[i]._subscription.url == subscription.url) |
| 397 return children[i]; | 405 return children[i]; |
| 398 return null; | 406 return null; |
| 399 } | 407 } |
| 400 | 408 |
| 401 function updateSubscriptionInfo(element) | 409 function updateSubscriptionInfo(element, subscription) |
| 402 { | 410 { |
| 403 var subscription = element._subscription; | 411 if (subscription) |
| 412 element._subscription = subscription; | |
| 413 else | |
| 414 subscription = element._subscription; | |
| 404 | 415 |
| 405 var title = element.getElementsByClassName("subscriptionTitle")[0]; | 416 var title = element.getElementsByClassName("subscriptionTitle")[0]; |
| 406 title.textContent = subscription.title; | 417 title.textContent = subscription.title; |
| 407 title.setAttribute("title", subscription.url); | 418 title.setAttribute("title", subscription.url); |
| 408 if (subscription.homepage) | 419 if (subscription.homepage) |
| 409 title.href = subscription.homepage; | 420 title.href = subscription.homepage; |
| 410 else | 421 else |
| 411 title.href = subscription.url; | 422 title.href = subscription.url; |
| 412 | 423 |
| 413 var enabled = element.getElementsByClassName("subscriptionEnabled")[0]; | 424 var enabled = element.getElementsByClassName("subscriptionEnabled")[0]; |
| 414 enabled.checked = !subscription.disabled; | 425 enabled.checked = !subscription.disabled; |
| 415 | 426 |
| 416 var lastUpdate = element.getElementsByClassName("subscriptionUpdate")[0]; | 427 var lastUpdate = element.getElementsByClassName("subscriptionUpdate")[0]; |
| 417 lastUpdate.classList.remove("error"); | 428 lastUpdate.classList.remove("error"); |
| 418 if (Synchronizer.isExecuting(subscription.url)) | 429 |
| 419 lastUpdate.textContent = i18n.getMessage("filters_subscription_lastDownload_ inProgress"); | 430 if (subscription.downloadStatus && |
| 420 else if (subscription.downloadStatus && subscription.downloadStatus != "synchr onize_ok") | 431 subscription.downloadStatus != "synchronize_ok") |
| 421 { | 432 { |
| 422 var map = | 433 var map = |
| 423 { | 434 { |
| 424 "synchronize_invalid_url": "filters_subscription_lastDownload_invalidURL", | 435 "synchronize_invalid_url": "filters_subscription_lastDownload_invalidURL" , |
| 425 "synchronize_connection_error": "filters_subscription_lastDownload_connect ionError", | 436 "synchronize_connection_error": "filters_subscription_lastDownload_connec tionError", |
| 426 "synchronize_invalid_data": "filters_subscription_lastDownload_invalidData ", | 437 "synchronize_invalid_data": "filters_subscription_lastDownload_invalidDat a", |
| 427 "synchronize_checksum_mismatch": "filters_subscription_lastDownload_checks umMismatch" | 438 "synchronize_checksum_mismatch": "filters_subscription_lastDownload_check sumMismatch" |
| 428 }; | 439 }; |
| 429 if (subscription.downloadStatus in map) | 440 if (subscription.downloadStatus in map) |
| 430 lastUpdate.textContent = i18n.getMessage(map[subscription.downloadStatus]) ; | 441 lastUpdate.textContent = i18n.getMessage(map[subscription.downloadStatus] ); |
| 431 else | 442 else |
| 432 lastUpdate.textContent = subscription.downloadStatus; | 443 lastUpdate.textContent = subscription.downloadStatus; |
| 433 lastUpdate.classList.add("error"); | 444 lastUpdate.classList.add("error"); |
| 434 } | 445 } |
| 435 else if (subscription.lastDownload > 0) | 446 else if (subscription.lastDownload > 0) |
| 436 { | 447 { |
| 437 var timeDate = i18n_timeDateStrings(subscription.lastDownload * 1000); | 448 var timeDate = i18n_timeDateStrings(subscription.lastDownload * 1000); |
| 438 var messageID = (timeDate[1] ? "last_updated_at" : "last_updated_at_today"); | 449 var messageID = (timeDate[1] ? "last_updated_at" : "last_updated_at_today"); |
| 439 lastUpdate.textContent = i18n.getMessage(messageID, timeDate); | 450 lastUpdate.textContent = i18n.getMessage(messageID, timeDate); |
| 440 } | 451 } |
| 441 } | 452 } |
| 442 | 453 |
| 443 function onSubscriptionChange(subscription) | 454 function onSubscriptionMessage(action, subscription) |
| 444 { | 455 { |
| 445 var element = findSubscriptionElement(subscription); | 456 switch (action) |
| 446 if (element) | |
| 447 updateSubscriptionInfo(element); | |
| 448 } | |
| 449 | |
| 450 function onSubscriptionAdded(subscription) | |
| 451 { | |
| 452 if (subscription instanceof SpecialSubscription) | |
| 453 { | 457 { |
| 454 for (var i = 0; i < subscription.filters.length; i++) | 458 case "title": |
| 455 onFilterAdded(subscription.filters[i]); | 459 case "disabled": |
| 456 } | 460 case "homepage": |
| 457 else if (subscription.url == Prefs.subscriptions_exceptionsurl) | 461 case "lastDownload": |
| 458 $("#acceptableAds").prop("checked", true); | 462 case "downloadStatus": |
| 459 else if (!findSubscriptionElement(subscription)) | 463 var element = findSubscriptionElement(subscription); |
| 460 addSubscriptionEntry(subscription); | 464 if (element) |
| 461 } | 465 updateSubscriptionInfo(element, subscription); |
| 462 | 466 break; |
| 463 function onSubscriptionRemoved(subscription) | 467 case "added": |
| 464 { | 468 getPref("subscriptions_exceptionsurl", function (acceptableAdsUrl) |
| 465 if (subscription instanceof SpecialSubscription) | 469 { |
| 466 { | 470 if (subscription.url == acceptableAdsUrl) |
| 467 for (var i = 0; i < subscription.filters.length; i++) | 471 $("#acceptableAds").prop("checked", true); |
| 468 onFilterRemoved(subscription.filters[i]); | 472 else if (!findSubscriptionElement(subscription)) |
| 469 } | 473 addSubscriptionEntry(subscription); |
| 470 else if (subscription.url == Prefs.subscriptions_exceptionsurl) | 474 }); |
| 471 $("#acceptableAds").prop("checked", false); | 475 break; |
| 472 else | 476 case "removed": |
| 473 { | 477 getPref("subscriptions_exceptionsurl", function (acceptableAdsUrl) |
| 474 var element = findSubscriptionElement(subscription); | 478 { |
| 475 if (element) | 479 if (subscription.url == acceptableAdsUrl) |
| 476 element.parentNode.removeChild(element); | 480 { |
| 481 $("#acceptableAds").prop("checked", false); | |
| 482 } | |
| 483 else | |
| 484 { | |
| 485 var element = findSubscriptionElement(subscription); | |
| 486 if (element) | |
| 487 element.parentNode.removeChild(element); | |
| 488 } | |
| 489 }); | |
| 490 break; | |
| 477 } | 491 } |
| 478 } | 492 } |
| 479 | 493 |
| 480 function onFilterAdded(filter) | 494 function onPrefMessage(key, value) |
| 481 { | 495 { |
| 482 if (filter instanceof WhitelistFilter && | 496 if (key == "notifications_showui") |
|
Sebastian Noack
2016/04/03 15:05:14
Nit: There will be soon a third case for safari_co
kzar
2016/04/03 15:50:19
Done.
| |
| 483 /^@@\|\|([^\/:]+)\^\$document$/.test(filter.text)) | 497 { |
| 484 appendToListBox("excludedDomainsBox", RegExp.$1); | 498 document.getElementById("shouldShowNotificationsContainer").hidden = !value; |
| 485 else | 499 return; |
| 486 appendToListBox("userFiltersBox", filter.text); | 500 } |
| 501 else if (key == "notifications_ignoredcategories") | |
| 502 { | |
| 503 key = "shouldShowNotifications"; | |
| 504 value = value.indexOf("*") == -1; | |
| 505 } | |
| 506 | |
| 507 var checkbox = document.getElementById(key); | |
| 508 if (checkbox) | |
| 509 checkbox.checked = value; | |
| 487 } | 510 } |
| 488 | 511 |
| 489 function onFilterRemoved(filter) | 512 function onFilterMessage(action, filter) |
| 490 { | 513 { |
| 491 if (filter instanceof WhitelistFilter && | 514 switch (action) |
| 492 /^@@\|\|([^\/:]+)\^\$document$/.test(filter.text)) | 515 { |
| 493 removeFromListBox("excludedDomainsBox", RegExp.$1); | 516 case "loaded": |
| 494 else | 517 reloadFilters(); |
| 495 removeFromListBox("userFiltersBox", filter.text); | 518 break; |
| 519 case "added": | |
| 520 if (whitelistedDomainRegexp.test(filter.text)) | |
| 521 appendToListBox("excludedDomainsBox", RegExp.$1); | |
| 522 else | |
| 523 appendToListBox("userFiltersBox", filter.text); | |
| 524 break; | |
| 525 case "removed": | |
| 526 if (whitelistedDomainRegexp.test(filter.text)) | |
| 527 removeFromListBox("excludedDomainsBox", RegExp.$1); | |
| 528 else | |
| 529 removeFromListBox("userFiltersBox", filter.text); | |
| 530 break; | |
| 531 } | |
| 496 } | 532 } |
| 497 | 533 |
| 498 // Populates a list box with a number of entries | 534 function clearListBox(id) |
| 499 function populateList(id, entries) | |
| 500 { | 535 { |
| 501 var list = document.getElementById(id); | 536 var list = document.getElementById(id); |
| 502 while (list.lastChild) | 537 while (list.lastChild) |
| 503 list.removeChild(list.lastChild); | 538 list.removeChild(list.lastChild); |
| 504 | |
| 505 entries.sort(); | |
| 506 for (var i = 0; i < entries.length; i++) | |
| 507 { | |
| 508 var option = new Option(); | |
| 509 option.text = entries[i]; | |
| 510 option.value = entries[i]; | |
| 511 list.appendChild(option); | |
| 512 } | |
| 513 } | 539 } |
| 514 | 540 |
| 515 // Add a filter string to the list box. | 541 // Add a filter string to the list box. |
| 516 function appendToListBox(boxId, text) | 542 function appendToListBox(boxId, text) |
| 517 { | 543 { |
| 518 var elt = new Option(); /* Note: document.createElement("option") is unreliab le in Opera */ | 544 // Note: document.createElement("option") is unreliable in Opera |
| 545 var elt = new Option(); | |
| 519 elt.text = text; | 546 elt.text = text; |
| 520 elt.value = text; | 547 elt.value = text; |
| 521 document.getElementById(boxId).appendChild(elt); | 548 document.getElementById(boxId).appendChild(elt); |
| 522 } | 549 } |
| 523 | 550 |
| 524 // Remove a filter string from a list box. | 551 // Remove a filter string from a list box. |
| 525 function removeFromListBox(boxId, text) | 552 function removeFromListBox(boxId, text) |
| 526 { | 553 { |
| 527 var list = document.getElementById(boxId); | 554 var list = document.getElementById(boxId); |
| 528 for (var i = 0; i < list.length; i++) | 555 for (var i = 0; i < list.length; i++) |
| 529 if (list.options[i].value == text) | 556 if (list.options[i].value == text) |
| 530 list.remove(i--); | 557 list.remove(i--); |
| 531 } | 558 } |
| 532 | 559 |
| 533 function addWhitelistDomain(event) | 560 function addWhitelistDomain(event) |
| 534 { | 561 { |
| 535 event.preventDefault(); | 562 event.preventDefault(); |
| 536 | 563 |
| 537 var domain = document.getElementById("newWhitelistDomain").value.replace(/\s/g , ""); | 564 var domain = document.getElementById("newWhitelistDomain").value.replace(/\s/g , ""); |
| 538 document.getElementById("newWhitelistDomain").value = ""; | 565 document.getElementById("newWhitelistDomain").value = ""; |
| 539 if (!domain) | 566 if (!domain) |
| 540 return; | 567 return; |
| 541 | 568 |
| 542 var filterText = "@@||" + domain + "^$document"; | 569 var filterText = "@@||" + domain + "^$document"; |
| 543 FilterStorage.addFilter(Filter.fromText(filterText)); | 570 addFilter(filterText); |
| 544 } | 571 } |
| 545 | 572 |
| 546 // Adds filter text that user typed to the selection box | 573 // Adds filter text that user typed to the selection box |
| 547 function addTypedFilter(event) | 574 function addTypedFilter(event) |
| 548 { | 575 { |
| 549 event.preventDefault(); | 576 event.preventDefault(); |
| 550 | 577 |
| 551 var element = document.getElementById("newFilter"); | 578 var element = document.getElementById("newFilter"); |
| 552 var result = parseFilter(element.value); | 579 addFilter(element.value, function (errors) |
| 553 | |
| 554 if (result.error) | |
| 555 { | 580 { |
| 556 alert(result.error); | 581 if (errors.length > 0) |
| 557 return; | 582 alert(errors.join("\n")); |
| 558 } | 583 else |
| 559 | 584 element.value = ""; |
| 560 if (result.filter) | 585 }); |
| 561 FilterStorage.addFilter(result.filter); | |
| 562 | |
| 563 element.value = ""; | |
| 564 } | 586 } |
| 565 | 587 |
| 566 // Removes currently selected whitelisted domains | 588 // Removes currently selected whitelisted domains |
| 567 function removeSelectedExcludedDomain(event) | 589 function removeSelectedExcludedDomain(event) |
| 568 { | 590 { |
| 569 event.preventDefault(); | 591 event.preventDefault(); |
| 570 var excludedDomainsBox = document.getElementById("excludedDomainsBox"); | 592 var excludedDomainsBox = document.getElementById("excludedDomainsBox"); |
| 571 var remove = []; | 593 var remove = []; |
| 572 for (var i = 0; i < excludedDomainsBox.length; i++) | 594 for (var i = 0; i < excludedDomainsBox.length; i++) |
| 573 if (excludedDomainsBox.options[i].selected) | 595 if (excludedDomainsBox.options[i].selected) |
| 574 remove.push(excludedDomainsBox.options[i].value); | 596 remove.push(excludedDomainsBox.options[i].value); |
| 575 if (!remove.length) | 597 if (!remove.length) |
| 576 return; | 598 return; |
| 577 | 599 |
| 578 for (var i = 0; i < remove.length; i++) | 600 for (var i = 0; i < remove.length; i++) |
| 579 FilterStorage.removeFilter(Filter.fromText("@@||" + remove[i] + "^$document" )); | 601 removeFilter("@@||" + remove[i] + "^$document"); |
| 580 } | 602 } |
| 581 | 603 |
| 582 // Removes all currently selected filters | 604 // Removes all currently selected filters |
| 583 function removeSelectedFilters(event) | 605 function removeSelectedFilters(event) |
| 584 { | 606 { |
| 585 event.preventDefault(); | 607 event.preventDefault(); |
| 586 var userFiltersBox = document.getElementById("userFiltersBox"); | 608 var userFiltersBox = document.getElementById("userFiltersBox"); |
| 587 var remove = []; | 609 var remove = []; |
| 588 for (var i = 0; i < userFiltersBox.length; i++) | 610 for (var i = 0; i < userFiltersBox.length; i++) |
| 589 if (userFiltersBox.options[i].selected) | 611 if (userFiltersBox.options[i].selected) |
| 590 remove.push(userFiltersBox.options[i].value); | 612 remove.push(userFiltersBox.options[i].value); |
| 591 if (!remove.length) | 613 if (!remove.length) |
| 592 return; | 614 return; |
| 593 | 615 |
| 594 for (var i = 0; i < remove.length; i++) | 616 for (var i = 0; i < remove.length; i++) |
| 595 FilterStorage.removeFilter(Filter.fromText(remove[i])); | 617 removeFilter(remove[i]); |
| 596 } | 618 } |
| 597 | 619 |
| 598 // Shows raw filters box and fills it with the current user filters | 620 // Shows raw filters box and fills it with the current user filters |
| 599 function toggleFiltersInRawFormat(event) | 621 function toggleFiltersInRawFormat(event) |
| 600 { | 622 { |
| 601 event.preventDefault(); | 623 event.preventDefault(); |
| 602 | 624 |
| 603 $("#rawFilters").toggle(); | 625 $("#rawFilters").toggle(); |
| 604 if ($("#rawFilters").is(":visible")) | 626 if ($("#rawFilters").is(":visible")) |
| 605 { | 627 { |
| 606 var userFiltersBox = document.getElementById("userFiltersBox"); | 628 var userFiltersBox = document.getElementById("userFiltersBox"); |
| 607 var text = ""; | 629 var text = ""; |
| 608 for (var i = 0; i < userFiltersBox.length; i++) | 630 for (var i = 0; i < userFiltersBox.length; i++) |
| 609 text += userFiltersBox.options[i].value + "\n"; | 631 text += userFiltersBox.options[i].value + "\n"; |
| 610 document.getElementById("rawFiltersText").value = text; | 632 document.getElementById("rawFiltersText").value = text; |
| 611 } | 633 } |
| 612 } | 634 } |
| 613 | 635 |
| 614 // Imports filters in the raw text box | 636 // Imports filters in the raw text box |
| 615 function importRawFiltersText() | 637 function importRawFiltersText() |
| 616 { | 638 { |
| 617 var text = document.getElementById("rawFiltersText").value; | 639 var text = document.getElementById("rawFiltersText").value; |
| 618 var result = parseFilters(text); | |
| 619 | 640 |
| 620 var errors = result.errors.filter(function(e) | 641 importRawFilters(text, function (errors) |
| 621 { | 642 { |
| 622 return e.type != "unexpected-filter-list-header"; | 643 if (errors.length > 0) |
| 644 alert(errors.join("\n")); | |
| 645 else | |
| 646 $("#rawFilters").hide(); | |
| 623 }); | 647 }); |
| 624 | |
| 625 if (errors.length > 0) | |
| 626 { | |
| 627 alert(errors.join("\n")); | |
| 628 return; | |
| 629 } | |
| 630 | |
| 631 var seenFilter = Object.create(null); | |
| 632 for (var i = 0; i < result.filters.length; i++) | |
| 633 { | |
| 634 var filter = result.filters[i]; | |
| 635 FilterStorage.addFilter(filter); | |
| 636 seenFilter[filter.text] = null; | |
| 637 } | |
| 638 | |
| 639 var remove = []; | |
| 640 for (var i = 0; i < FilterStorage.subscriptions.length; i++) | |
| 641 { | |
| 642 var subscription = FilterStorage.subscriptions[i]; | |
| 643 if (!(subscription instanceof SpecialSubscription)) | |
| 644 continue; | |
| 645 | |
| 646 for (var j = 0; j < subscription.filters.length; j++) | |
| 647 { | |
| 648 var filter = subscription.filters[j]; | |
| 649 if (filter instanceof WhitelistFilter && /^@@\|\|([^\/:]+)\^\$document$/.t est(filter.text)) | |
| 650 continue; | |
| 651 | |
| 652 if (!(filter.text in seenFilter)) | |
| 653 remove.push(filter); | |
| 654 } | |
| 655 } | |
| 656 | |
| 657 for (var i = 0; i < remove.length; i++) | |
| 658 FilterStorage.removeFilter(remove[i]); | |
| 659 | |
| 660 $("#rawFilters").hide(); | |
| 661 } | 648 } |
| 662 | 649 |
| 663 // Called when user explicitly requests filter list updates | 650 // Called when user explicitly requests filter list updates |
| 664 function updateFilterLists() | 651 function updateFilterLists() |
| 665 { | 652 { |
| 666 for (var i = 0; i < FilterStorage.subscriptions.length; i++) | 653 // Without the URL parameter this will update all subscriptions |
| 654 updateSubscription(); | |
| 655 | |
| 656 // Display a message for any subscriptions that are currently being downloaded | |
| 657 getSubscriptions(true, false, function(subscriptions) | |
| 667 { | 658 { |
| 668 var subscription = FilterStorage.subscriptions[i]; | 659 var inProgressMessage = i18n.getMessage( |
| 669 if (subscription instanceof DownloadableSubscription) | 660 "filters_subscription_lastDownload_inProgress" |
| 670 Synchronizer.execute(subscription, true, true); | 661 ); |
| 671 } | 662 |
| 663 for (var i = 0; i < subscriptions.length; i += 1) | |
| 664 { | |
| 665 var element = findSubscriptionElement(subscriptions[i]); | |
| 666 if (element) | |
| 667 { | |
| 668 var label = element.getElementsByClassName("subscriptionUpdate")[0]; | |
| 669 isSubscriptionDownloading(subscriptions[i].url, function (isDownloading) | |
|
Sebastian Noack
2016/04/03 15:11:41
Nit: Redundant space after function statement.
kzar
2016/04/03 15:50:19
Done.
| |
| 670 { | |
| 671 if (isDownloading) | |
| 672 label.textContent = inProgressMessage; | |
|
Sebastian Noack
2016/04/03 15:27:40
This will always be the label of the last subscrip
kzar
2016/04/03 16:11:33
Oops, you're right. Done.
| |
| 673 }); | |
| 674 } | |
| 675 } | |
| 676 }); | |
| 672 } | 677 } |
| 673 | 678 |
| 674 // Adds a subscription entry to the UI. | 679 // Adds a subscription entry to the UI. |
| 675 function addSubscriptionEntry(subscription) | 680 function addSubscriptionEntry(subscription) |
| 676 { | 681 { |
| 677 var template = document.getElementById("subscriptionTemplate"); | 682 var template = document.getElementById("subscriptionTemplate"); |
| 678 var element = template.cloneNode(true); | 683 var element = template.cloneNode(true); |
| 679 element.removeAttribute("id"); | 684 element.removeAttribute("id"); |
| 680 element._subscription = subscription; | 685 element._subscription = subscription; |
| 681 | 686 |
| 682 var removeButton = element.getElementsByClassName("subscriptionRemoveButton")[ 0]; | 687 var removeButton = element.getElementsByClassName("subscriptionRemoveButton")[ 0]; |
| 683 removeButton.setAttribute("title", removeButton.textContent); | 688 removeButton.setAttribute("title", removeButton.textContent); |
| 684 removeButton.textContent = "\xD7"; | 689 removeButton.textContent = "\xD7"; |
| 685 removeButton.addEventListener("click", function() | 690 removeButton.addEventListener("click", function() |
| 686 { | 691 { |
| 687 if (!confirm(i18n.getMessage("global_remove_subscription_warning"))) | 692 if (!confirm(i18n.getMessage("global_remove_subscription_warning"))) |
| 688 return; | 693 return; |
| 689 | 694 |
| 690 FilterStorage.removeSubscription(subscription); | 695 removeSubscription(subscription.url); |
| 691 }, false); | 696 }, false); |
| 692 if (Prefs.additional_subscriptions.indexOf(subscription.url) != -1) | 697 |
| 693 removeButton.style.visibility = "hidden"; | 698 getPref("additional_subscriptions", function (additionalSubscriptions) |
| 699 { | |
| 700 if (additionalSubscriptions.indexOf(subscription.url) != -1) | |
| 701 removeButton.style.visibility = "hidden"; | |
| 702 }); | |
| 694 | 703 |
| 695 var enabled = element.getElementsByClassName("subscriptionEnabled")[0]; | 704 var enabled = element.getElementsByClassName("subscriptionEnabled")[0]; |
| 696 enabled.addEventListener("click", function() | 705 enabled.addEventListener("click", function() |
| 697 { | 706 { |
| 698 if (subscription.disabled == !enabled.checked) | 707 subscription.disabled = !subscription.disabled; |
| 699 return; | 708 toggleSubscription(subscription.url, true); |
| 700 | |
| 701 subscription.disabled = !enabled.checked; | |
| 702 }, false); | 709 }, false); |
| 703 | 710 |
| 704 updateSubscriptionInfo(element); | 711 updateSubscriptionInfo(element); |
| 705 | 712 |
| 706 document.getElementById("filterLists").appendChild(element); | 713 document.getElementById("filterLists").appendChild(element); |
| 707 } | 714 } |
| 708 | 715 |
| 709 function setLinks(id) | 716 function setLinks(id) |
| 710 { | 717 { |
| 711 var element = document.getElementById(id); | 718 var element = document.getElementById(id); |
| 712 if (!element) | 719 if (!element) |
| 713 return; | 720 return; |
| 714 | 721 |
| 715 var links = element.getElementsByTagName("a"); | 722 var links = element.getElementsByTagName("a"); |
| 716 for (var i = 0; i < links.length; i++) | 723 for (var i = 0; i < links.length; i++) |
| 717 { | 724 { |
| 718 if (typeof arguments[i + 1] == "string") | 725 if (typeof arguments[i + 1] == "string") |
| 719 { | 726 { |
| 720 links[i].href = arguments[i + 1]; | 727 links[i].href = arguments[i + 1]; |
| 721 links[i].setAttribute("target", "_blank"); | 728 links[i].setAttribute("target", "_blank"); |
| 722 } | 729 } |
| 723 else if (typeof arguments[i + 1] == "function") | 730 else if (typeof arguments[i + 1] == "function") |
| 724 { | 731 { |
| 725 links[i].href = "javascript:void(0);"; | 732 links[i].href = "javascript:void(0);"; |
| 726 links[i].addEventListener("click", arguments[i + 1], false); | 733 links[i].addEventListener("click", arguments[i + 1], false); |
| 727 } | 734 } |
| 728 } | 735 } |
| 729 } | 736 } |
| 737 | |
| 738 ext.onMessage.addListener(function(message) | |
| 739 { | |
| 740 switch (message.type) | |
| 741 { | |
| 742 case "app.respond": | |
| 743 if (message.action == "addSubscription") | |
| 744 { | |
| 745 var subscription = message.args[0]; | |
| 746 startSubscriptionSelection(subscription.title, subscription.url); | |
| 747 } | |
| 748 break; | |
| 749 case "focus-section": | |
|
Sebastian Noack
2016/04/03 15:05:14
This should be handled the same way app.respond[ad
kzar
2016/04/03 15:50:19
Done. (Not tested yet as leaving for airport short
| |
| 750 var tabs = document.getElementsByClassName("ui-tabs-panel"); | |
| 751 for (var i = 0; i < tabs.length; i++) | |
| 752 { | |
| 753 var found = tabs[i].querySelector( | |
| 754 "[data-section='" + message.section + "']" | |
| 755 ); | |
| 756 if (!found) | |
| 757 continue; | |
| 758 | |
| 759 var previous = document.getElementsByClassName("focused"); | |
| 760 if (previous.length > 0) | |
| 761 previous[0].classList.remove("focused"); | |
| 762 | |
| 763 var tab = $("[href='#" + tabs[i].id + "']"); | |
| 764 $("#tabs").tabs("select", tab.parent().index()); | |
| 765 found.classList.add("focused"); | |
| 766 } | |
| 767 break; | |
| 768 case "filters.respond": | |
| 769 onFilterMessage(message.action, message.args[0]); | |
| 770 break; | |
| 771 case "prefs.respond": | |
| 772 onPrefMessage(message.action, message.args[0]); | |
| 773 break; | |
| 774 case "subscriptions.respond": | |
| 775 onSubscriptionMessage(message.action, message.args[0]); | |
| 776 break; | |
| 777 } | |
| 778 }); | |
| OLD | NEW |