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

Side by Side Diff: new-options.js

Issue 29411555: Issue 5169 - Add whitelisted tab to the new options page (Closed)
Patch Set: Addressed latest comments Created May 22, 2017, 9:35 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
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, text) 48 Collection.prototype._setEmpty = function(table, texts)
48 { 49 {
49 let placeholder = table.querySelector(".empty-placeholder"); 50 let placeholders = table.querySelectorAll(".empty-placeholder");
50 if (text && !placeholder) 51
52 if (texts && placeholders.length == 0)
51 { 53 {
52 placeholder = document.createElement("li"); 54 for (let text of texts)
53 placeholder.className = "empty-placeholder"; 55 {
54 placeholder.textContent = getMessage(text); 56 let placeholder = document.createElement("li");
55 table.appendChild(placeholder); 57 placeholder.className = "empty-placeholder";
58 placeholder.textContent = getMessage(text);
59 table.appendChild(placeholder);
60 }
56 } 61 }
57 else if (placeholder) 62 else if (placeholders.length > 0)
58 table.removeChild(placeholder); 63 {
64 for (let placeholder of placeholders)
65 table.removeChild(placeholder);
66 }
59 }; 67 };
60 68
61 Collection.prototype._createElementQuery = function(item) 69 Collection.prototype._createElementQuery = function(item)
62 { 70 {
63 let access = (item.url || item.text).replace(/'/g, "\\'"); 71 let access = (item.url || item.text).replace(/'/g, "\\'");
64 return function(container) 72 return function(container)
65 { 73 {
66 return container.querySelector("[data-access='" + access + "']"); 74 return container.querySelector("[data-access='" + access + "']");
67 }; 75 };
68 }; 76 };
(...skipping 16 matching lines...) Expand all
85 this.items.sort((a, b) => 93 this.items.sort((a, b) =>
86 { 94 {
87 // Make sure that Acceptable Ads is always last, since it cannot be 95 // Make sure that Acceptable Ads is always last, since it cannot be
88 // disabled, but only be removed. That way it's grouped together with 96 // disabled, but only be removed. That way it's grouped together with
89 // the "Own filter list" which cannot be disabled either at the bottom 97 // the "Own filter list" which cannot be disabled either at the bottom
90 // of the filter lists in the Advanced tab. 98 // of the filter lists in the Advanced tab.
91 if (a.url == acceptableAdsUrl) 99 if (a.url == acceptableAdsUrl)
92 return 1; 100 return 1;
93 if (b.url == acceptableAdsUrl) 101 if (b.url == acceptableAdsUrl)
94 return -1; 102 return -1;
103 if (a[timestampUI])
104 return b[timestampUI] ? b[timestampUI] - a[timestampUI] : -1;
105 if (b[timestampUI])
106 return a[timestampUI] ? a[timestampUI] - b[timestampUI] : 1;
Thomas Greiner 2017/05/26 11:10:39 This condition is duplicated and contradictory bec
Thomas Greiner 2017/05/26 11:10:40 Detail: Please add a comment as we did with the sp
saroyanm 2017/05/31 08:30:27 Done.
saroyanm 2017/05/31 08:30:28 Done.
95 107
96 let aTitle = this._getItemTitle(a, 0).toLowerCase(); 108 let aTitle = this._getItemTitle(a, 0).toLowerCase();
97 let bTitle = this._getItemTitle(b, 0).toLowerCase(); 109 let bTitle = this._getItemTitle(b, 0).toLowerCase();
98 return aTitle.localeCompare(bTitle); 110 return aTitle.localeCompare(bTitle);
99 }); 111 });
100 112
101 for (let j = 0; j < this.details.length; j++) 113 for (let j = 0; j < this.details.length; j++)
102 { 114 {
103 let table = E(this.details[j].id); 115 let table = E(this.details[j].id);
104 let template = table.querySelector("template"); 116 let template = table.querySelector("template");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 let title = this._getItemTitle(item, i); 202 let title = this._getItemTitle(item, i);
191 element.querySelector(".display").textContent = title; 203 element.querySelector(".display").textContent = title;
192 element.setAttribute("aria-label", title); 204 element.setAttribute("aria-label", title);
193 if (this.details[i].searchable) 205 if (this.details[i].searchable)
194 element.setAttribute("data-search", title.toLowerCase()); 206 element.setAttribute("data-search", title.toLowerCase());
195 let control = element.querySelector(".control[role='checkbox']"); 207 let control = element.querySelector(".control[role='checkbox']");
196 if (control) 208 if (control)
197 { 209 {
198 control.setAttribute("aria-checked", item.disabled == false); 210 control.setAttribute("aria-checked", item.disabled == false);
199 if (item.url == acceptableAdsUrl && this == collections.filterLists) 211 if (item.url == acceptableAdsUrl && this == collections.filterLists)
200 control.setAttribute("disabled", true); 212 control.disabled = true;
201 } 213 }
202 214
203 let dateElement = element.querySelector(".date"); 215 let dateElement = element.querySelector(".date");
204 let timeElement = element.querySelector(".time"); 216 let timeElement = element.querySelector(".time");
205 if (dateElement && timeElement) 217 if (dateElement && timeElement)
206 { 218 {
207 let message = element.querySelector(".message"); 219 let message = element.querySelector(".message");
208 if (item.isDownloading) 220 if (item.isDownloading)
209 { 221 {
210 let text = getMessage("options_filterList_lastDownload_inProgress"); 222 let text = getMessage("options_filterList_lastDownload_inProgress");
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 } 290 }
279 291
280 collections.popular = new Collection([ 292 collections.popular = new Collection([
281 { 293 {
282 id: "recommend-list-table" 294 id: "recommend-list-table"
283 } 295 }
284 ]); 296 ]);
285 collections.langs = new Collection([ 297 collections.langs = new Collection([
286 { 298 {
287 id: "blocking-languages-table", 299 id: "blocking-languages-table",
288 emptyText: "options_dialog_language_added_empty" 300 emptyText: ["options_dialog_language_added_empty"]
289 }, 301 },
290 { 302 {
291 id: "blocking-languages-dialog-table", 303 id: "blocking-languages-dialog-table",
292 emptyText: "options_dialog_language_added_empty" 304 emptyText: ["options_dialog_language_added_empty"]
293 } 305 }
294 ]); 306 ]);
295 collections.allLangs = new Collection([ 307 collections.allLangs = new Collection([
296 { 308 {
297 id: "all-lang-table", 309 id: "all-lang-table",
298 emptyText: "options_dialog_language_other_empty", 310 emptyText: ["options_dialog_language_other_empty"],
299 searchable: true 311 searchable: true
300 } 312 }
301 ]); 313 ]);
302 collections.acceptableAds = new Collection([ 314 collections.acceptableAds = new Collection([
303 { 315 {
304 id: "acceptableads-table" 316 id: "acceptableads-table"
305 } 317 }
306 ]); 318 ]);
307 collections.custom = new Collection([ 319 collections.custom = new Collection([
308 { 320 {
309 id: "custom-list-table" 321 id: "custom-list-table"
310 } 322 }
311 ]); 323 ]);
312 collections.whitelist = new Collection([ 324 collections.whitelist = new Collection([
313 { 325 {
314 id: "whitelisting-table", 326 id: "whitelisting-table",
315 emptyText: "options_whitelisted_empty" 327 emptyText: ["options_whitelist_empty_1", "options_whitelist_empty_2"]
316 } 328 }
317 ]); 329 ]);
318 collections.customFilters = new Collection([ 330 collections.customFilters = new Collection([
319 { 331 {
320 id: "custom-filters-table", 332 id: "custom-filters-table",
321 emptyText: "options_customFilters_empty" 333 emptyText: ["options_customFilters_empty"]
322 } 334 }
323 ]); 335 ]);
324 collections.filterLists = new Collection([ 336 collections.filterLists = new Collection([
325 { 337 {
326 id: "all-filter-lists-table", 338 id: "all-filter-lists-table",
327 useOriginalTitle: true 339 useOriginalTitle: true
328 } 340 }
329 ]); 341 ]);
330 342
331 function toggleShowLanguage(subscription) 343 function toggleShowLanguage(subscription)
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 let dialog = E("dialog-content-predefined"); 500 let dialog = E("dialog-content-predefined");
489 let title = dialog.querySelector("h3").textContent; 501 let title = dialog.querySelector("h3").textContent;
490 let url = dialog.querySelector(".url").textContent; 502 let url = dialog.querySelector(".url").textContent;
491 addEnableSubscription(url, title); 503 addEnableSubscription(url, title);
492 closeDialog(); 504 closeDialog();
493 break; 505 break;
494 } 506 }
495 case "cancel-custom-filters": 507 case "cancel-custom-filters":
496 E("custom-filters").classList.remove("mode-edit"); 508 E("custom-filters").classList.remove("mode-edit");
497 break; 509 break;
498 case "cancel-domain-exception":
499 E("whitelisting-textbox").value = "";
500 document.querySelector("#whitelisting .controls").classList
501 .remove("mode-edit");
502 break;
503 case "close-dialog": 510 case "close-dialog":
504 closeDialog(); 511 closeDialog();
505 break; 512 break;
506 case "edit-custom-filters": 513 case "edit-custom-filters":
507 editCustomFilters(); 514 editCustomFilters();
508 break; 515 break;
509 case "edit-domain-exception":
510 document.querySelector("#whitelisting .controls").classList
511 .add("mode-edit");
512 E("whitelisting-textbox").focus();
513 break;
514 case "import-subscription": { 516 case "import-subscription": {
515 let url = E("blockingList-textbox").value; 517 let url = E("blockingList-textbox").value;
516 addEnableSubscription(url); 518 addEnableSubscription(url);
517 closeDialog(); 519 closeDialog();
518 break; 520 break;
519 } 521 }
520 case "open-context-menu": { 522 case "open-context-menu": {
521 let listItem = findParentData(element, "access", true); 523 let listItem = findParentData(element, "access", true);
522 if (listItem && !listItem.classList.contains("show-context-menu")) 524 if (listItem && !listItem.classList.contains("show-context-menu"))
523 listItem.classList.add("show-context-menu"); 525 listItem.classList.add("show-context-menu");
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 745
744 updateShareLink(); 746 updateShareLink();
745 updateTooltips(); 747 updateTooltips();
746 748
747 // Initialize interactive UI elements 749 // Initialize interactive UI elements
748 document.body.addEventListener("click", onClick, false); 750 document.body.addEventListener("click", onClick, false);
749 document.body.addEventListener("keyup", onKeyUp, false); 751 document.body.addEventListener("keyup", onKeyUp, false);
750 let placeholderValue = getMessage("options_dialog_language_find"); 752 let placeholderValue = getMessage("options_dialog_language_find");
751 E("find-language").setAttribute("placeholder", placeholderValue); 753 E("find-language").setAttribute("placeholder", placeholderValue);
752 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); 754 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
753 E("whitelisting-textbox").addEventListener("keypress", (e) => 755 let exampleValue = getMessages("options_whitelist_placeholder_example",
756 ["www.example.com"]);
757 E("whitelisting-textbox").setAttribute("placeholder", exampleValue);
758 E("whitelisting-textbox").addEventListener("keyup", (e) =>
754 { 759 {
760 let addWhitelistButton = E("whitelisting-add-button");
761 addWhitelistButton.disabled = false;
755 if (getKey(e) == "Enter") 762 if (getKey(e) == "Enter")
756 addWhitelistedDomain(); 763 {
764 if (!addWhitelistButton.disabled)
765 addWhitelistedDomain();
766 }
767 else
768 {
769 if (!e.target.value)
770 {
771 addWhitelistButton.disabled = true;
Thomas Greiner 2017/05/26 11:10:39 Detail: Now that we reduced it to a simple check,
saroyanm 2017/05/31 08:30:27 Done.
772 }
773 }
757 }, false); 774 }, false);
758 775
759 // Advanced tab 776 // Advanced tab
760 let tweaks = document.querySelectorAll("#tweaks li[data-pref]"); 777 let tweaks = document.querySelectorAll("#tweaks li[data-pref]");
761 tweaks = Array.prototype.map.call(tweaks, (checkbox) => 778 tweaks = Array.prototype.map.call(tweaks, (checkbox) =>
762 { 779 {
763 return checkbox.getAttribute("data-pref"); 780 return checkbox.getAttribute("data-pref");
764 }); 781 });
765 for (let key of tweaks) 782 for (let key of tweaks)
766 { 783 {
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 { 972 {
956 for (let subscription of subscriptions) 973 for (let subscription of subscriptions)
957 onSubscriptionMessage("added", subscription); 974 onSubscriptionMessage("added", subscription);
958 }); 975 });
959 }); 976 });
960 } 977 }
961 978
962 function addWhitelistedDomain() 979 function addWhitelistedDomain()
963 { 980 {
964 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 collections.whitelist.removeItem(whitelistItem);
987 whitelistItem[timestampUI] = Date.now();
988 collections.whitelist.addItem(whitelistItem);
Thomas Greiner 2017/05/26 11:10:40 Removing and then adding the item again is quite a
saroyanm 2017/05/30 12:30:43 I agree with you. The problem is that we are curr
saroyanm 2017/05/31 08:30:27 Done.
989 domain.value = "";
Thomas Greiner 2017/05/26 11:10:39 No need to continue the loop because we already fo
saroyanm 2017/05/31 08:30:27 Done.
990 }
991 }
965 if (domain.value) 992 if (domain.value)
966 { 993 {
967 sendMessageHandleErrors({ 994 sendMessageHandleErrors({
968 type: "filters.add", 995 type: "filters.add",
969 text: "@@||" + domain.value.toLowerCase() + "^$document" 996 text: "@@||" + domain.value.toLowerCase() + "^$document"
970 }); 997 });
971 } 998 }
972 999
973 domain.value = ""; 1000 domain.value = "";
974 document.querySelector("#whitelisting .controls") 1001 E("whitelisting-add-button").disabled = true;
975 .classList.remove("mode-edit");
976 } 1002 }
977 1003
978 function editCustomFilters() 1004 function editCustomFilters()
979 { 1005 {
980 if (!isCustomFiltersLoaded) 1006 if (!isCustomFiltersLoaded)
981 { 1007 {
982 console.error("Custom filters are not loaded"); 1008 console.error("Custom filters are not loaded");
983 return; 1009 return;
984 } 1010 }
985 1011
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 }); 1315 });
1290 ext.backgroundPage.sendMessage({ 1316 ext.backgroundPage.sendMessage({
1291 type: "subscriptions.listen", 1317 type: "subscriptions.listen",
1292 filter: ["added", "disabled", "homepage", "lastDownload", "removed", 1318 filter: ["added", "disabled", "homepage", "lastDownload", "removed",
1293 "title", "downloadStatus", "downloading"] 1319 "title", "downloadStatus", "downloading"]
1294 }); 1320 });
1295 1321
1296 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 1322 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
1297 window.addEventListener("hashchange", onHashChange, false); 1323 window.addEventListener("hashchange", onHashChange, false);
1298 } 1324 }
OLDNEW
« new-options.html ('K') | « new-options.html ('k') | skin/new-options.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld