Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: new-options.js

Issue 29411555: Issue 5169 - Add whitelisted tab to the new options page (Closed)
Left Patch Set: Rebased to changeset #109 Created May 19, 2017, 12:47 p.m.
Right Patch Set: Fixed the TYPO Created July 3, 2017, 4:10 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « new-options.html ('k') | skin/new-options.css » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
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
(...skipping 19 matching lines...) Expand all
30 let filterErrors = new Map([ 30 let filterErrors = new Map([
31 ["synchronize_invalid_url", 31 ["synchronize_invalid_url",
32 "options_filterList_lastDownload_invalidURL"], 32 "options_filterList_lastDownload_invalidURL"],
33 ["synchronize_connection_error", 33 ["synchronize_connection_error",
34 "options_filterList_lastDownload_connectionError"], 34 "options_filterList_lastDownload_connectionError"],
35 ["synchronize_invalid_data", 35 ["synchronize_invalid_data",
36 "options_filterList_lastDownload_invalidData"], 36 "options_filterList_lastDownload_invalidData"],
37 ["synchronize_checksum_mismatch", 37 ["synchronize_checksum_mismatch",
38 "options_filterList_lastDownload_checksumMismatch"] 38 "options_filterList_lastDownload_checksumMismatch"]
39 ]); 39 ]);
40 const timestampUI = Symbol();
40 41
41 function Collection(details) 42 function Collection(details)
42 { 43 {
43 this.details = details; 44 this.details = details;
44 this.items = []; 45 this.items = [];
45 } 46 }
46 47
47 Collection.prototype._setEmpty = function(table, texts) 48 Collection.prototype._setEmpty = function(table, texts)
48 { 49 {
49 let placeholders = table.querySelectorAll(".empty-placeholder"); 50 let placeholders = table.querySelectorAll(".empty-placeholder");
(...skipping 26 matching lines...) Expand all
76 77
77 Collection.prototype._getItemTitle = function(item, i) 78 Collection.prototype._getItemTitle = function(item, i)
78 { 79 {
79 if (item.url == acceptableAdsUrl) 80 if (item.url == acceptableAdsUrl)
80 return getMessage("options_acceptableAds_description"); 81 return getMessage("options_acceptableAds_description");
81 if (this.details[i].useOriginalTitle && item.originalTitle) 82 if (this.details[i].useOriginalTitle && item.originalTitle)
82 return item.originalTitle; 83 return item.originalTitle;
83 return item.title || item.url || item.text; 84 return item.title || item.url || item.text;
84 }; 85 };
85 86
86 Collection.prototype.addItem = function(item) 87 Collection.prototype._sortItems = function()
87 { 88 {
88 if (this.items.indexOf(item) >= 0)
89 return;
90
91 this.items.push(item);
92 this.items.sort((a, b) => 89 this.items.sort((a, b) =>
93 { 90 {
94 // Make sure that Acceptable Ads is always last, since it cannot be 91 // Make sure that Acceptable Ads is always last, since it cannot be
95 // disabled, but only be removed. That way it's grouped together with 92 // disabled, but only be removed. That way it's grouped together with
96 // the "Own filter list" which cannot be disabled either at the bottom 93 // the "Own filter list" which cannot be disabled either at the bottom
97 // of the filter lists in the Advanced tab. 94 // of the filter lists in the Advanced tab.
98 if (a.url == acceptableAdsUrl) 95 if (a.url == acceptableAdsUrl)
99 return 1; 96 return 1;
100 if (b.url == acceptableAdsUrl) 97 if (b.url == acceptableAdsUrl)
101 return -1; 98 return -1;
102 99
100 // Make sure that newly added entries always appear on top in descending
101 // chronological order
102 let aTimestamp = a[timestampUI] || 0;
103 let bTimestamp = b[timestampUI] || 0;
104 if (aTimestamp || bTimestamp)
105 return bTimestamp - aTimestamp;
106
103 let aTitle = this._getItemTitle(a, 0).toLowerCase(); 107 let aTitle = this._getItemTitle(a, 0).toLowerCase();
104 let bTitle = this._getItemTitle(b, 0).toLowerCase(); 108 let bTitle = this._getItemTitle(b, 0).toLowerCase();
105 return aTitle.localeCompare(bTitle); 109 return aTitle.localeCompare(bTitle);
106 }); 110 });
107 111 };
112
113 Collection.prototype.addItem = function(item)
114 {
115 if (this.items.indexOf(item) >= 0)
116 return;
117
118 this.items.push(item);
119 this._sortItems();
108 for (let j = 0; j < this.details.length; j++) 120 for (let j = 0; j < this.details.length; j++)
109 { 121 {
110 let table = E(this.details[j].id); 122 let table = E(this.details[j].id);
111 let template = table.querySelector("template"); 123 let template = table.querySelector("template");
112 let listItem = document.createElement("li"); 124 let listItem = document.createElement("li");
113 listItem.appendChild(document.importNode(template.content, true)); 125 listItem.appendChild(document.importNode(template.content, true));
114 listItem.setAttribute("aria-label", this._getItemTitle(item, j)); 126 listItem.setAttribute("aria-label", this._getItemTitle(item, j));
115 listItem.setAttribute("data-access", item.url || item.text); 127 listItem.setAttribute("data-access", item.url || item.text);
116 listItem.setAttribute("role", "section"); 128 listItem.setAttribute("role", "section");
117 129
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 } 191 }
180 192
181 element.parentElement.removeChild(element); 193 element.parentElement.removeChild(element);
182 if (this.items.length == 0) 194 if (this.items.length == 0)
183 this._setEmpty(table, detail.emptyText); 195 this._setEmpty(table, detail.emptyText);
184 } 196 }
185 }; 197 };
186 198
187 Collection.prototype.updateItem = function(item) 199 Collection.prototype.updateItem = function(item)
188 { 200 {
201 let oldIndex = this.items.indexOf(item);
202 this._sortItems();
189 let access = (item.url || item.text).replace(/'/g, "\\'"); 203 let access = (item.url || item.text).replace(/'/g, "\\'");
190 for (let i = 0; i < this.details.length; i++) 204 for (let i = 0; i < this.details.length; i++)
191 { 205 {
192 let table = E(this.details[i].id); 206 let table = E(this.details[i].id);
193 let element = table.querySelector("[data-access='" + access + "']"); 207 let element = table.querySelector("[data-access='" + access + "']");
194 if (!element) 208 if (!element)
195 continue; 209 continue;
196 210
197 let title = this._getItemTitle(item, i); 211 let title = this._getItemTitle(item, i);
198 element.querySelector(".display").textContent = title; 212 element.querySelector(".display").textContent = title;
199 element.setAttribute("aria-label", title); 213 element.setAttribute("aria-label", title);
200 if (this.details[i].searchable) 214 if (this.details[i].searchable)
201 element.setAttribute("data-search", title.toLowerCase()); 215 element.setAttribute("data-search", title.toLowerCase());
202 let control = element.querySelector(".control[role='checkbox']"); 216 let control = element.querySelector(".control[role='checkbox']");
203 if (control) 217 if (control)
204 { 218 {
205 control.setAttribute("aria-checked", item.disabled == false); 219 control.setAttribute("aria-checked", item.disabled == false);
206 if (item.url == acceptableAdsUrl && this == collections.filterLists) 220 if (item.url == acceptableAdsUrl && this == collections.filterLists)
207 control.setAttribute("disabled", true); 221 control.disabled = true;
208 } 222 }
209 223
210 let dateElement = element.querySelector(".date"); 224 let dateElement = element.querySelector(".date");
211 let timeElement = element.querySelector(".time"); 225 let timeElement = element.querySelector(".time");
212 if (dateElement && timeElement) 226 if (dateElement && timeElement)
213 { 227 {
214 let message = element.querySelector(".message"); 228 let message = element.querySelector(".message");
215 if (item.isDownloading) 229 if (item.isDownloading)
216 { 230 {
217 let text = getMessage("options_filterList_lastDownload_inProgress"); 231 let text = getMessage("options_filterList_lastDownload_inProgress");
(...skipping 23 matching lines...) Expand all
241 { 255 {
242 if (item.homepage) 256 if (item.homepage)
243 websiteElement.setAttribute("href", item.homepage); 257 websiteElement.setAttribute("href", item.homepage);
244 else 258 else
245 websiteElement.setAttribute("aria-hidden", true); 259 websiteElement.setAttribute("aria-hidden", true);
246 } 260 }
247 261
248 let sourceElement = element.querySelector(".context-menu .source"); 262 let sourceElement = element.querySelector(".context-menu .source");
249 if (sourceElement) 263 if (sourceElement)
250 sourceElement.setAttribute("href", item.url); 264 sourceElement.setAttribute("href", item.url);
265
266 let newIndex = this.items.indexOf(item);
267 if (oldIndex != newIndex)
268 table.insertBefore(element, table.childNodes[newIndex]);
251 } 269 }
252 }; 270 };
253 271
254 Collection.prototype.clearAll = function() 272 Collection.prototype.clearAll = function()
255 { 273 {
256 this.items = []; 274 this.items = [];
257 for (let detail of this.details) 275 for (let detail of this.details)
258 { 276 {
259 let table = E(detail.id); 277 let table = E(detail.id);
260 let element = table.firstChild; 278 let element = table.firstChild;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 758
741 updateShareLink(); 759 updateShareLink();
742 updateTooltips(); 760 updateTooltips();
743 761
744 // Initialize interactive UI elements 762 // Initialize interactive UI elements
745 document.body.addEventListener("click", onClick, false); 763 document.body.addEventListener("click", onClick, false);
746 document.body.addEventListener("keyup", onKeyUp, false); 764 document.body.addEventListener("keyup", onKeyUp, false);
747 let placeholderValue = getMessage("options_dialog_language_find"); 765 let placeholderValue = getMessage("options_dialog_language_find");
748 E("find-language").setAttribute("placeholder", placeholderValue); 766 E("find-language").setAttribute("placeholder", placeholderValue);
749 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); 767 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
750 let exampleValue = getMessage("options_whitelist_placeholder_example"); 768 let exampleValue = getMessage("options_whitelist_placeholder_example",
769 ["www.example.com"]);
751 E("whitelisting-textbox").setAttribute("placeholder", exampleValue); 770 E("whitelisting-textbox").setAttribute("placeholder", exampleValue);
752 E("whitelisting-textbox").addEventListener("keyup", (e) => 771 E("whitelisting-textbox").addEventListener("keyup", (e) =>
753 { 772 {
754 let addWhitelistButton = E("whitelisting-add-button"); 773 E("whitelisting-add-button").disabled = !e.target.value;
755 addWhitelistButton.disabled = false;
756 if (getKey(e) == "Enter")
757 {
758 if (!addWhitelistButton.disabled)
759 addWhitelistedDomain();
760 }
761 else
762 {
763 for (let whitelistItem of collections.whitelist.items)
764 {
765 if (!e.target.value)
766 {
767 addWhitelistButton.disabled = true;
768 }
769 if (whitelistItem.title == e.target.value)
770 {
771 addWhitelistButton.disabled = true;
772 E("whitelisting-validation").textContent =
773 getMessage("options_whitelist_duplicate");
Thomas Greiner 2017/05/26 11:10:38 Detail: This text doesn't appear to be used anymor
774 }
775 }
776 }
777 }, false); 774 }, false);
778 775
779 // Advanced tab 776 // Advanced tab
780 let tweaks = document.querySelectorAll("#tweaks li[data-pref]"); 777 let tweaks = document.querySelectorAll("#tweaks li[data-pref]");
781 tweaks = Array.prototype.map.call(tweaks, (checkbox) => 778 tweaks = Array.prototype.map.call(tweaks, (checkbox) =>
782 { 779 {
783 return checkbox.getAttribute("data-pref"); 780 return checkbox.getAttribute("data-pref");
784 }); 781 });
785 for (let key of tweaks) 782 for (let key of tweaks)
786 { 783 {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
975 { 972 {
976 for (let subscription of subscriptions) 973 for (let subscription of subscriptions)
977 onSubscriptionMessage("added", subscription); 974 onSubscriptionMessage("added", subscription);
978 }); 975 });
979 }); 976 });
980 } 977 }
981 978
982 function addWhitelistedDomain() 979 function addWhitelistedDomain()
983 { 980 {
984 let domain = E("whitelisting-textbox"); 981 let domain = E("whitelisting-textbox");
982 for (let whitelistItem of collections.whitelist.items)
983 {
984 if (whitelistItem.title == domain.value)
985 {
986 whitelistItem[timestampUI] = Date.now();
987 collections.whitelist.updateItem(whitelistItem);
988 domain.value = "";
989 break;
990 }
991 }
985 if (domain.value) 992 if (domain.value)
986 { 993 {
987 sendMessageHandleErrors({ 994 sendMessageHandleErrors({
988 type: "filters.add", 995 type: "filters.add",
989 text: "@@||" + domain.value.toLowerCase() + "^$document" 996 text: "@@||" + domain.value.toLowerCase() + "^$document"
990 }); 997 });
991 } 998 }
992 999
993 domain.value = ""; 1000 domain.value = "";
994 E("whitelisting-add-button").disabled = true; 1001 E("whitelisting-add-button").disabled = true;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 message.homepage = homepage; 1035 message.homepage = homepage;
1029 1036
1030 ext.backgroundPage.sendMessage(message); 1037 ext.backgroundPage.sendMessage(message);
1031 } 1038 }
1032 1039
1033 function onFilterMessage(action, filter) 1040 function onFilterMessage(action, filter)
1034 { 1041 {
1035 switch (action) 1042 switch (action)
1036 { 1043 {
1037 case "added": 1044 case "added":
1045 filter[timestampUI] = Date.now();
1038 updateFilter(filter); 1046 updateFilter(filter);
1039 updateShareLink(); 1047 updateShareLink();
1040 break; 1048 break;
1041 case "loaded": 1049 case "loaded":
1042 populateLists(); 1050 populateLists();
1043 break; 1051 break;
1044 case "removed": 1052 case "removed":
1045 let knownFilter = filtersMap[filter.text]; 1053 let knownFilter = filtersMap[filter.text];
1046 collections.whitelist.removeItem(knownFilter); 1054 collections.whitelist.removeItem(knownFilter);
1047 collections.customFilters.removeItem(knownFilter); 1055 collections.customFilters.removeItem(knownFilter);
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 }); 1316 });
1309 ext.backgroundPage.sendMessage({ 1317 ext.backgroundPage.sendMessage({
1310 type: "subscriptions.listen", 1318 type: "subscriptions.listen",
1311 filter: ["added", "disabled", "homepage", "lastDownload", "removed", 1319 filter: ["added", "disabled", "homepage", "lastDownload", "removed",
1312 "title", "downloadStatus", "downloading"] 1320 "title", "downloadStatus", "downloading"]
1313 }); 1321 });
1314 1322
1315 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 1323 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
1316 window.addEventListener("hashchange", onHashChange, false); 1324 window.addEventListener("hashchange", onHashChange, false);
1317 } 1325 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld