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 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 | 56 |
57 Collection.prototype._createElementQuery = function(item) | 57 Collection.prototype._createElementQuery = function(item) |
58 { | 58 { |
59 var access = (item.url || item.text).replace(/'/g, "\\'"); | 59 var access = (item.url || item.text).replace(/'/g, "\\'"); |
60 return function(container) | 60 return function(container) |
61 { | 61 { |
62 return container.querySelector("[data-access='" + access + "']"); | 62 return container.querySelector("[data-access='" + access + "']"); |
63 }; | 63 }; |
64 }; | 64 }; |
65 | 65 |
66 Collection.prototype._isControlDisabled = function(item, i) | |
67 { | |
68 return item.url == acceptableAdsUrl && | |
69 this.details[i].onClick == toggleDisableSubscription; | |
70 }; | |
71 | |
72 Collection.prototype._getItemTitle = function(item, i) | 66 Collection.prototype._getItemTitle = function(item, i) |
73 { | 67 { |
74 var title = null; | 68 var title = null; |
75 if (this.details[i].useOriginalTitle) | 69 if (this.details[i].useOriginalTitle) |
76 title = item.originalTitle; | 70 title = item.originalTitle; |
77 if (!title) | 71 if (!title) |
78 title = item.title || item.url || item.text; | 72 title = item.title || item.url || item.text; |
79 return title; | 73 return title; |
80 }; | 74 }; |
81 | 75 |
82 Collection.prototype.addItems = function() | 76 Collection.prototype.addItems = function() |
83 { | 77 { |
84 var length = Array.prototype.push.apply(this.items, arguments); | 78 var length = Array.prototype.push.apply(this.items, arguments); |
85 if (length == 0) | 79 if (length == 0) |
86 return; | 80 return; |
87 | 81 |
88 this.items.sort(function(a, b) | 82 this.items.sort(function(a, b) |
89 { | 83 { |
90 var aDisabled = this._isControlDisabled(a, 0); | 84 // Make sure that Acceptable Ads is always last, since it cannot be |
91 var bDisabled = this._isControlDisabled(b, 0); | 85 // disabled, but only be removed. That way it's grouped together with |
92 if (aDisabled != bDisabled) | 86 // the "Own filter list" which cannot be disabled either at the bottom |
93 return aDisabled - bDisabled; | 87 // of the filter lists in the Advanced tab. |
| 88 if (a.url == acceptableAdsUrl) |
| 89 return 1; |
| 90 if (b.url == acceptableAdsUrl) |
| 91 return -1; |
94 | 92 |
95 var aTitle = this._getItemTitle(a, 0).toLowerCase(); | 93 var aTitle = this._getItemTitle(a, 0).toLowerCase(); |
96 var bTitle = this._getItemTitle(b, 0).toLowerCase(); | 94 var bTitle = this._getItemTitle(b, 0).toLowerCase(); |
97 return aTitle.localeCompare(bTitle); | 95 return aTitle.localeCompare(bTitle); |
98 }.bind(this)); | 96 }.bind(this)); |
99 | 97 |
100 for (var j = 0; j < this.details.length; j++) | 98 for (var j = 0; j < this.details.length; j++) |
101 { | 99 { |
102 var table = E(this.details[j].id); | 100 var table = E(this.details[j].id); |
103 var template = table.querySelector("template"); | 101 var template = table.querySelector("template"); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
191 continue; | 189 continue; |
192 | 190 |
193 var title = this._getItemTitle(item, i); | 191 var title = this._getItemTitle(item, i); |
194 element.querySelector(".display").textContent = title; | 192 element.querySelector(".display").textContent = title; |
195 if (title) | 193 if (title) |
196 element.setAttribute("data-search", title.toLowerCase()); | 194 element.setAttribute("data-search", title.toLowerCase()); |
197 var control = element.querySelector(".control[role='checkbox']"); | 195 var control = element.querySelector(".control[role='checkbox']"); |
198 if (control) | 196 if (control) |
199 { | 197 { |
200 control.setAttribute("aria-checked", item.disabled == false); | 198 control.setAttribute("aria-checked", item.disabled == false); |
201 if (this._isControlDisabled(item, i)) | 199 if (item.url == acceptableAdsUrl && this.details[i].onClick == |
| 200 toggleDisableSubscription) |
202 control.setAttribute("disabled", true); | 201 control.setAttribute("disabled", true); |
203 } | 202 } |
204 | 203 |
205 var downloadStatus = item.downloadStatus; | |
206 var dateElement = element.querySelector(".date"); | 204 var dateElement = element.querySelector(".date"); |
207 var timeElement = element.querySelector(".time"); | 205 var timeElement = element.querySelector(".time"); |
208 if(dateElement && timeElement) | 206 if (dateElement && timeElement) |
209 { | 207 { |
210 var message = element.querySelector(".message"); | 208 var message = element.querySelector(".message"); |
211 ext.backgroundPage.sendMessage( | 209 if (item.isDownloading) |
212 { | 210 { |
213 type: "subscriptions.isDownloading", | 211 var text = getMessage("options_filterList_lastDownload_inProgress"); |
214 url: item.url | 212 message.textContent = text; |
215 }, | 213 element.classList.add("show-message"); |
216 function(isDownloading) | 214 } |
217 { | 215 else if (item.downloadStatus != "synchronize_ok") |
218 if (isDownloading) | 216 { |
219 { | 217 var error = filterErrors[item.downloadStatus]; |
220 var text = getMessage("options_filterList_lastDownload_inProgress"); | 218 if (error) |
221 message.textContent = text; | 219 message.textContent = getMessage(error); |
222 element.classList.add("show-message"); | 220 else |
223 } | 221 message.textContent = item.downloadStatus; |
224 else if (downloadStatus && downloadStatus != "synchronize_ok") | 222 element.classList.add("show-message"); |
225 { | 223 } |
226 if (downloadStatus in filterErrors) | 224 else if (item.lastDownload > 0) |
227 message.textContent = getMessage(filterErrors[downloadStatus]); | 225 { |
228 else | 226 var dateTime = i18n_formatDateTime(item.lastDownload * 1000); |
229 message.textContent = item.downloadStatus; | 227 dateElement.textContent = dateTime[0]; |
230 element.classList.add("show-message"); | 228 timeElement.textContent = dateTime[1]; |
231 } | 229 element.classList.remove("show-message"); |
232 else if (item.lastDownload > 0) | 230 } |
233 { | 231 } |
234 var dateTime = i18n_formatDateTime(item.lastDownload * 1000); | 232 |
235 dateElement.textContent = dateTime[0]; | |
236 timeElement.textContent = dateTime[1]; | |
237 element.classList.remove("show-message"); | |
238 } | |
239 }); | |
240 } | |
241 var websiteElement = element.querySelector(".context-menu .website"); | 233 var websiteElement = element.querySelector(".context-menu .website"); |
242 var sourceElement = element.querySelector(".context-menu .source"); | 234 var sourceElement = element.querySelector(".context-menu .source"); |
243 if (websiteElement && item.homepage) | 235 if (websiteElement && item.homepage) |
244 websiteElement.setAttribute("href", item.homepage); | 236 websiteElement.setAttribute("href", item.homepage); |
245 if (sourceElement) | 237 if (sourceElement) |
246 sourceElement.setAttribute("href", item.url); | 238 sourceElement.setAttribute("href", item.url); |
247 } | 239 } |
248 }; | 240 }; |
249 | 241 |
250 Collection.prototype.clearAll = function() | 242 Collection.prototype.clearAll = function() |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 collections.allLangs.removeItem(subscription); | 397 collections.allLangs.removeItem(subscription); |
406 collections.langs.addItems(subscription); | 398 collections.langs.addItems(subscription); |
407 } | 399 } |
408 else | 400 else |
409 { | 401 { |
410 collections.allLangs.addItems(subscription); | 402 collections.allLangs.addItems(subscription); |
411 collections.langs.removeItem(subscription); | 403 collections.langs.removeItem(subscription); |
412 } | 404 } |
413 } | 405 } |
414 } | 406 } |
415 for (var i in collections) | 407 } |
416 collections[i].updateItem(subscription); | 408 |
417 } | 409 for (var name in collections) |
| 410 collections[name].updateItem(subscription); |
418 } | 411 } |
419 | 412 |
420 if (!Object.observe) | 413 if (!Object.observe) |
421 { | 414 { |
422 ["disabled", "lastDownload"].forEach(function(property) | 415 Object.keys(subscription).forEach(function(property) |
423 { | 416 { |
424 subscription["$" + property] = subscription[property]; | 417 var value = subscription[property]; |
425 Object.defineProperty(subscription, property, | 418 Object.defineProperty(subscription, property, |
426 { | 419 { |
427 get: function() | 420 get: function() |
428 { | 421 { |
429 return this["$" + property]; | 422 return value; |
430 }, | 423 }, |
431 set: function(newValue) | 424 set: function(newValue) |
432 { | 425 { |
433 var oldValue = this["$" + property]; | 426 if (value != newValue) |
434 if (oldValue != newValue) | |
435 { | 427 { |
436 this["$" + property] = newValue; | 428 value = newValue; |
437 var change = Object.create(null); | 429 onObjectChanged([{name: property}]); |
438 change.name = property; | |
439 onObjectChanged([change]); | |
440 } | 430 } |
441 } | 431 } |
442 }); | 432 }); |
443 }); | 433 }); |
444 } | 434 } |
445 else | 435 else |
446 { | 436 { |
447 Object.observe(subscription, onObjectChanged); | 437 Object.observe(subscription, onObjectChanged); |
448 } | 438 } |
449 } | 439 } |
450 | 440 |
451 function updateSubscription(subscription) | 441 function updateSubscription(subscription) |
452 { | 442 { |
453 var subscriptionUrl = subscription.url; | 443 var subscriptionUrl = subscription.url; |
454 var knownSubscription = subscriptionsMap[subscriptionUrl]; | 444 var knownSubscription = subscriptionsMap[subscriptionUrl]; |
455 if (knownSubscription) | 445 if (knownSubscription) |
456 { | 446 { |
457 for (var property in subscription) | 447 for (var property in subscription) |
458 if (property != "title") | 448 { |
| 449 if (property == "title" && subscriptionUrl in recommendationsMap) |
| 450 knownSubscription.originalTitle = subscription.title; |
| 451 else |
459 knownSubscription[property] = subscription[property]; | 452 knownSubscription[property] = subscription[property]; |
| 453 } |
460 } | 454 } |
461 else | 455 else |
462 { | 456 { |
463 observeSubscription(subscription); | 457 observeSubscription(subscription); |
464 | 458 |
465 var collection; | 459 var collection; |
466 if (subscriptionUrl in recommendationsMap) | 460 if (subscriptionUrl in recommendationsMap) |
467 { | 461 { |
468 var recommendation = recommendationsMap[subscriptionUrl]; | 462 var recommendation = recommendationsMap[subscriptionUrl]; |
469 if (recommendation.type != "ads") | 463 if (recommendation.type != "ads") |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 var knownSubscription = subscriptionsMap[subscription.url]; | 968 var knownSubscription = subscriptionsMap[subscription.url]; |
975 if (knownSubscription) | 969 if (knownSubscription) |
976 collections.filterLists.addItems(knownSubscription); | 970 collections.filterLists.addItems(knownSubscription); |
977 else | 971 else |
978 collections.filterLists.addItems(subscription); | 972 collections.filterLists.addItems(subscription); |
979 break; | 973 break; |
980 case "disabled": | 974 case "disabled": |
981 updateSubscription(subscription); | 975 updateSubscription(subscription); |
982 updateShareLink(); | 976 updateShareLink(); |
983 break; | 977 break; |
984 case "lastDownload": | |
985 updateSubscription(subscription); | |
986 break; | |
987 case "homepage": | |
988 // TODO: NYI | |
989 break; | |
990 case "removed": | 978 case "removed": |
991 var knownSubscription = subscriptionsMap[subscription.url]; | 979 var knownSubscription = subscriptionsMap[subscription.url]; |
992 if (subscription.url == acceptableAdsUrl) | 980 if (subscription.url == acceptableAdsUrl) |
993 { | 981 { |
994 subscription.disabled = true; | 982 subscription.disabled = true; |
995 updateSubscription(subscription); | 983 updateSubscription(subscription); |
996 } | 984 } |
997 else | 985 else |
998 { | 986 { |
999 if (subscription.url in recommendationsMap) | 987 if (subscription.url in recommendationsMap) |
1000 knownSubscription.disabled = true; | 988 knownSubscription.disabled = true; |
1001 else | 989 else |
1002 { | 990 { |
1003 collections.custom.removeItem(knownSubscription); | 991 collections.custom.removeItem(knownSubscription); |
1004 delete subscriptionsMap[subscription.url]; | 992 delete subscriptionsMap[subscription.url]; |
1005 } | 993 } |
1006 } | 994 } |
1007 updateShareLink(); | 995 updateShareLink(); |
1008 collections.filterLists.removeItem(knownSubscription); | 996 collections.filterLists.removeItem(knownSubscription); |
1009 break; | 997 break; |
1010 case "title": | 998 default: |
1011 // TODO: NYI | 999 updateSubscription(subscription); |
1012 break; | 1000 break; |
1013 } | 1001 } |
1014 } | 1002 } |
1015 | 1003 |
1016 function hidePref(key, value) | 1004 function hidePref(key, value) |
1017 { | 1005 { |
1018 var element = document.querySelector("[data-pref='" + key + "']"); | 1006 var element = document.querySelector("[data-pref='" + key + "']"); |
1019 if (element) | 1007 if (element) |
1020 element.setAttribute("aria-hidden", value); | 1008 element.setAttribute("aria-hidden", value); |
1021 } | 1009 } |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 | 1101 |
1114 for (var i = 0; i < shareResources.length; i++) | 1102 for (var i = 0; i < shareResources.length; i++) |
1115 checkShareResource(shareResources[i], onResult); | 1103 checkShareResource(shareResources[i], onResult); |
1116 } | 1104 } |
1117 | 1105 |
1118 ext.onMessage.addListener(function(message) | 1106 ext.onMessage.addListener(function(message) |
1119 { | 1107 { |
1120 switch (message.type) | 1108 switch (message.type) |
1121 { | 1109 { |
1122 case "app.respond": | 1110 case "app.respond": |
1123 if (message.action == "addSubscription") | 1111 switch (message.action) |
1124 { | 1112 { |
1125 var subscription = message.args[0]; | 1113 case "addSubscription": |
1126 var dialog = E("dialog-content-predefined"); | 1114 var subscription = message.args[0]; |
1127 dialog.querySelector("h3").textContent = subscription.title || ""; | 1115 var dialog = E("dialog-content-predefined"); |
1128 dialog.querySelector(".url").textContent = subscription.url; | 1116 dialog.querySelector("h3").textContent = subscription.title || ""; |
1129 openDialog("predefined"); | 1117 dialog.querySelector(".url").textContent = subscription.url; |
| 1118 openDialog("predefined"); |
| 1119 break; |
| 1120 case "focusSection": |
| 1121 document.body.setAttribute("data-tab", message.args[0]); |
| 1122 break; |
1130 } | 1123 } |
1131 break; | 1124 break; |
1132 case "filters.respond": | 1125 case "filters.respond": |
1133 onFilterMessage(message.action, message.args[0]); | 1126 onFilterMessage(message.action, message.args[0]); |
1134 break; | 1127 break; |
1135 case "prefs.respond": | 1128 case "prefs.respond": |
1136 onPrefMessage(message.action, message.args[0], false); | 1129 onPrefMessage(message.action, message.args[0], false); |
1137 break; | 1130 break; |
1138 case "subscriptions.respond": | 1131 case "subscriptions.respond": |
1139 onSubscriptionMessage(message.action, message.args[0]); | 1132 onSubscriptionMessage(message.action, message.args[0]); |
1140 break; | 1133 break; |
1141 } | 1134 } |
1142 }); | 1135 }); |
1143 | 1136 |
1144 ext.backgroundPage.sendMessage( | 1137 ext.backgroundPage.sendMessage( |
1145 { | 1138 { |
1146 type: "app.listen", | 1139 type: "app.listen", |
1147 filter: ["addSubscription"] | 1140 filter: ["addSubscription", "focusSection"] |
1148 }); | 1141 }); |
1149 ext.backgroundPage.sendMessage( | 1142 ext.backgroundPage.sendMessage( |
1150 { | 1143 { |
1151 type: "filters.listen", | 1144 type: "filters.listen", |
1152 filter: ["added", "loaded", "removed"] | 1145 filter: ["added", "loaded", "removed"] |
1153 }); | 1146 }); |
1154 ext.backgroundPage.sendMessage( | 1147 ext.backgroundPage.sendMessage( |
1155 { | 1148 { |
1156 type: "prefs.listen", | 1149 type: "prefs.listen", |
1157 filter: ["notifications_ignoredcategories", "notifications_showui", | 1150 filter: ["notifications_ignoredcategories", "notifications_showui", |
1158 "safari_contentblocker", "show_devtools_panel", | 1151 "safari_contentblocker", "show_devtools_panel", |
1159 "shouldShowBlockElementMenu"] | 1152 "shouldShowBlockElementMenu"] |
1160 }); | 1153 }); |
1161 ext.backgroundPage.sendMessage( | 1154 ext.backgroundPage.sendMessage( |
1162 { | 1155 { |
1163 type: "subscriptions.listen", | 1156 type: "subscriptions.listen", |
1164 filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 1157 filter: ["added", "disabled", "homepage", "lastDownload", "removed", |
1165 "title"] | 1158 "title", "downloadStatus", "downloading"] |
1166 }); | 1159 }); |
1167 | 1160 |
1168 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1161 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); |
1169 })(); | 1162 })(); |
LEFT | RIGHT |