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

Side by Side Diff: new-options.js

Issue 29445590: Issue 5255 - Advanced tab (HTML, strings and functionality) (Closed)
Patch Set: HTML, Strings and functionality Created June 11, 2017, 3:22 p.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 20 matching lines...) Expand all
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 40
41 const whitelistedDomainRegexp = /^@@\|\|([^/:]+)\^\$document$/;
42
41 function Collection(details) 43 function Collection(details)
42 { 44 {
43 this.details = details; 45 this.details = details;
44 this.items = []; 46 this.items = [];
45 } 47 }
46 48
47 Collection.prototype._setEmpty = function(table, text) 49 Collection.prototype._setEmpty = function(table, text)
48 { 50 {
49 let placeholder = table.querySelector(".empty-placeholder"); 51 let placeholder = table.querySelector(".empty-placeholder");
50 if (text && !placeholder) 52 if (text && !placeholder)
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 if (b.url == acceptableAdsUrl) 95 if (b.url == acceptableAdsUrl)
94 return -1; 96 return -1;
95 97
96 let aTitle = this._getItemTitle(a, 0).toLowerCase(); 98 let aTitle = this._getItemTitle(a, 0).toLowerCase();
97 let bTitle = this._getItemTitle(b, 0).toLowerCase(); 99 let bTitle = this._getItemTitle(b, 0).toLowerCase();
98 return aTitle.localeCompare(bTitle); 100 return aTitle.localeCompare(bTitle);
99 }); 101 });
100 102
101 for (let j = 0; j < this.details.length; j++) 103 for (let j = 0; j < this.details.length; j++)
102 { 104 {
103 let table = E(this.details[j].id); 105 let detail = this.details[j];
106 let table = E(detail.id);
104 let template = table.querySelector("template"); 107 let template = table.querySelector("template");
105 let listItem = document.createElement("li"); 108 let listItem = document.createElement("li");
106 listItem.appendChild(document.importNode(template.content, true)); 109 listItem.appendChild(document.importNode(template.content, true));
107 listItem.setAttribute("aria-label", this._getItemTitle(item, j)); 110 listItem.setAttribute("aria-label", this._getItemTitle(item, j));
108 listItem.setAttribute("data-access", item.url || item.text); 111 listItem.setAttribute("data-access", item.url || item.text);
109 listItem.setAttribute("role", "section"); 112 listItem.setAttribute("role", "section");
110 113
111 let label = listItem.querySelector(".display"); 114 let label = listItem.querySelector(".display");
112 if (item.recommended && label.hasAttribute("data-tooltip")) 115 if (item.recommended && label.hasAttribute("data-tooltip"))
113 { 116 {
114 let tooltipId = label.getAttribute("data-tooltip"); 117 let tooltipId = label.getAttribute("data-tooltip");
115 tooltipId = tooltipId.replace("%value%", item.recommended); 118 tooltipId = tooltipId.replace("%value%", item.recommended);
116 label.setAttribute("data-tooltip", tooltipId); 119 label.setAttribute("data-tooltip", tooltipId);
117 } 120 }
118 121
119 for (let control of listItem.querySelectorAll(".control")) 122 for (let control of listItem.querySelectorAll(".control"))
120 { 123 {
121 if (control.hasAttribute("title")) 124 if (control.hasAttribute("title"))
122 { 125 {
123 let titleValue = getMessage(control.getAttribute("title")); 126 let titleValue = getMessage(control.getAttribute("title"));
124 control.setAttribute("title", titleValue); 127 control.setAttribute("title", titleValue);
125 } 128 }
126 } 129 }
127 130
128 this._setEmpty(table, null); 131 this._setEmpty(table, null);
129 if (table.hasChildNodes()) 132 if (table.hasChildNodes())
130 { 133 {
131 table.insertBefore(listItem, 134 let beforeIndex = this.items.indexOf(item) + (detail.useHeader == true);
132 table.childNodes[this.items.indexOf(item)]); 135 table.insertBefore(listItem, table.children[beforeIndex]);
133 } 136 }
134 else 137 else
138 {
135 table.appendChild(listItem); 139 table.appendChild(listItem);
140 }
136 this.updateItem(item); 141 this.updateItem(item);
137 } 142 }
138 return length; 143 return length;
139 }; 144 };
140 145
141 Collection.prototype.removeItem = function(item) 146 Collection.prototype.removeItem = function(item)
142 { 147 {
143 let index = this.items.indexOf(item); 148 let index = this.items.indexOf(item);
144 if (index == -1) 149 if (index == -1)
145 return; 150 return;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 if (this.details[i].searchable) 198 if (this.details[i].searchable)
194 element.setAttribute("data-search", title.toLowerCase()); 199 element.setAttribute("data-search", title.toLowerCase());
195 let control = element.querySelector(".control[role='checkbox']"); 200 let control = element.querySelector(".control[role='checkbox']");
196 if (control) 201 if (control)
197 { 202 {
198 control.setAttribute("aria-checked", item.disabled == false); 203 control.setAttribute("aria-checked", item.disabled == false);
199 if (item.url == acceptableAdsUrl && this == collections.filterLists) 204 if (item.url == acceptableAdsUrl && this == collections.filterLists)
200 control.setAttribute("disabled", true); 205 control.setAttribute("disabled", true);
201 } 206 }
202 207
203 let dateElement = element.querySelector(".date"); 208 let lastUpdateElem = element.querySelector(".last-update");
204 let timeElement = element.querySelector(".time"); 209 if (lastUpdateElem)
205 if (dateElement && timeElement)
206 { 210 {
207 let message = element.querySelector(".message"); 211 let message = element.querySelector(".message");
208 if (item.isDownloading) 212 if (item.isDownloading)
209 { 213 {
210 let text = getMessage("options_filterList_lastDownload_inProgress"); 214 let text = getMessage("options_filterList_lastDownload_inProgress");
211 message.textContent = text; 215 message.textContent = text;
212 element.classList.add("show-message"); 216 element.classList.add("show-message");
213 } 217 }
214 else if (item.downloadStatus != "synchronize_ok") 218 else if (item.downloadStatus != "synchronize_ok")
215 { 219 {
216 let error = filterErrors.get(item.downloadStatus); 220 let error = filterErrors.get(item.downloadStatus);
217 if (error) 221 if (error)
218 message.textContent = getMessage(error); 222 message.textContent = getMessage(error);
219 else 223 else
220 message.textContent = item.downloadStatus; 224 message.textContent = item.downloadStatus;
221 element.classList.add("show-message"); 225 element.classList.add("show-message");
222 } 226 }
223 else if (item.lastDownload > 0) 227 else if (item.lastDownload > 0)
224 { 228 {
225 let dateTime = i18nFormatDateTime(item.lastDownload * 1000); 229 let timer = setInterval(lastUpdateLive, 60000);
226 dateElement.textContent = dateTime[0]; 230 let lastUpdate = item.lastDownload * 1000;
227 timeElement.textContent = dateTime[1]; 231 function lastUpdateLive()
232 {
233 let sinceUpdate = Date.now() - lastUpdate;
234 if(sinceUpdate > 86400000)
235 {
236 let lastUpdateDate = new Date(item.lastDownload * 1000);
237 let monthName = lastUpdateDate.toLocaleString("en-US",
saroyanm 2017/06/11 15:40:12 For reference: Make sense to find a way to pass th
saroyanm 2017/06/12 16:44:42 Create a function in i18n, that returns month: "sh
saroyanm 2017/06/14 10:59:00 I used different approach while we do have the val
Thomas Greiner 2017/07/07 13:01:07 This looks like a race condition because the "lang
238 { month: "short" });
239 let day = lastUpdateDate.getDate();
240 day = day < 10 ? "0" + day : day;
241 lastUpdateElem.textContent = day + " " + monthName + " " +
saroyanm 2017/06/12 16:44:42 Note: Make sense to discuss if we need to localize
242 lastUpdateDate.getFullYear();
243 clearInterval(timer);
244 return;
245 }
246 else if (sinceUpdate > 3600000)
247 {
248 lastUpdateElem.textContent = Math.round(sinceUpdate / 3600000) +
249 " " + getMessage("options_filterList_hours");
250 }
251 else if (sinceUpdate > 60000)
252 {
253 lastUpdateElem.textContent = Math.round(sinceUpdate / 60000) +
254 " " + getMessage("options_filterList_minutes");
255 }
256 else
257 {
258 lastUpdateElem.textContent =
259 getMessage("options_filterList_just");
260 }
261 }
262 lastUpdateLive();
228 element.classList.remove("show-message"); 263 element.classList.remove("show-message");
229 } 264 }
230 } 265 }
231 266
232 let websiteElement = element.querySelector(".context-menu .website"); 267 let websiteElement = element.querySelector(".context-menu .website");
233 if (websiteElement) 268 if (websiteElement)
234 { 269 {
235 if (item.homepage) 270 if (item.homepage)
236 websiteElement.setAttribute("href", item.homepage); 271 websiteElement.setAttribute("href", item.homepage);
237 else 272 else
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 { 343 {
309 id: "custom-list-table" 344 id: "custom-list-table"
310 } 345 }
311 ]); 346 ]);
312 collections.whitelist = new Collection([ 347 collections.whitelist = new Collection([
313 { 348 {
314 id: "whitelisting-table", 349 id: "whitelisting-table",
315 emptyText: "options_whitelisted_empty" 350 emptyText: "options_whitelisted_empty"
316 } 351 }
317 ]); 352 ]);
318 collections.customFilters = new Collection([
319 {
320 id: "custom-filters-table",
321 emptyText: "options_customFilters_empty"
322 }
323 ]);
324 collections.filterLists = new Collection([ 353 collections.filterLists = new Collection([
325 { 354 {
326 id: "all-filter-lists-table", 355 id: "all-filter-lists-table",
327 useOriginalTitle: true 356 useOriginalTitle: true,
357 useHeader: true
328 } 358 }
329 ]); 359 ]);
330 360
331 function toggleShowLanguage(subscription) 361 function toggleShowLanguage(subscription)
332 { 362 {
333 if (subscription.recommended == "ads") 363 if (subscription.recommended == "ads")
334 { 364 {
335 if (subscription.disabled) 365 if (subscription.disabled)
336 { 366 {
337 collections.allLangs.addItem(subscription); 367 collections.allLangs.addItem(subscription);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 function updateSubscription(subscription) 401 function updateSubscription(subscription)
372 { 402 {
373 for (let name in collections) 403 for (let name in collections)
374 collections[name].updateItem(subscription); 404 collections[name].updateItem(subscription);
375 405
376 toggleShowLanguage(subscription); 406 toggleShowLanguage(subscription);
377 } 407 }
378 408
379 function updateFilter(filter) 409 function updateFilter(filter)
380 { 410 {
381 let match = filter.text.match(/^@@\|\|([^/:]+)\^\$document$/); 411 let match = filter.text.match(whitelistedDomainRegexp);
382 if (match && !filtersMap[filter.text]) 412 if (match && !filtersMap[filter.text])
383 { 413 {
384 filter.title = match[1]; 414 filter.title = match[1];
385 collections.whitelist.addItem(filter); 415 collections.whitelist.addItem(filter);
386 } 416 }
387 else 417 else
388 collections.customFilters.addItem(filter); 418 addCustomFilter(filter);
389 419
390 filtersMap[filter.text] = filter; 420 filtersMap[filter.text] = filter;
391 } 421 }
392 422
423 function addCustomFilter(filter)
424 {
425 customFiltersView("read");
426
427 // Note: document.createElement("option") is unreliable in Opera
saroyanm 2017/06/11 15:40:12 I'm not sure if this still true, I took this from
saroyanm 2017/06/12 16:44:42 Check if it's still an issue in the supported Oper
saroyanm 2017/06/14 10:59:00 Done. This was added back in 2012 -> https://hg.a
Thomas Greiner 2017/07/07 13:01:08 Acknowledged.
428 let elt = new Option();
429 elt.text = filter.text;
430 elt.value = filter.text;
431 E("custom-filters-box").appendChild(elt);
432 }
433
434 function removeCustomFilter(text)
435 {
436 let list = E("custom-filters-box");
437 let selector = "option[value=" + CSS.escape(text) + "]";
438 for (let option of list.querySelectorAll(selector))
439 list.removeChild(option);
440
441 if (E("custom-filters-box").options.length == 0)
442 customFiltersView("empty")
443 }
444
445 function convertToRawFormat(event)
446 {
447 let filters = [];
448
449 for (let option of E("custom-filters-box").options)
450 filters.push(option.value);
451
452 document.getElementById("custom-filters-raw").value = filters.join("\n");
453 }
454
393 function loadRecommendations() 455 function loadRecommendations()
394 { 456 {
395 fetch("subscriptions.xml") 457 fetch("subscriptions.xml")
396 .then((response) => 458 .then((response) =>
397 { 459 {
398 return response.text(); 460 return response.text();
399 }) 461 })
400 .then((text) => 462 .then((text) =>
401 { 463 {
402 let doc = new DOMParser().parseFromString(text, "application/xml"); 464 let doc = new DOMParser().parseFromString(text, "application/xml");
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 break; 548 break;
487 case "add-predefined-subscription": { 549 case "add-predefined-subscription": {
488 let dialog = E("dialog-content-predefined"); 550 let dialog = E("dialog-content-predefined");
489 let title = dialog.querySelector("h3").textContent; 551 let title = dialog.querySelector("h3").textContent;
490 let url = dialog.querySelector(".url").textContent; 552 let url = dialog.querySelector(".url").textContent;
491 addEnableSubscription(url, title); 553 addEnableSubscription(url, title);
492 closeDialog(); 554 closeDialog();
493 break; 555 break;
494 } 556 }
495 case "cancel-custom-filters": 557 case "cancel-custom-filters":
496 E("custom-filters").classList.remove("mode-edit"); 558 customFiltersView("read");
497 break; 559 break;
498 case "cancel-domain-exception": 560 case "cancel-domain-exception":
499 E("whitelisting-textbox").value = ""; 561 E("whitelisting-textbox").value = "";
500 document.querySelector("#whitelisting .controls").classList 562 document.querySelector("#whitelisting .controls").classList
501 .remove("mode-edit"); 563 .remove("mode-edit");
502 break; 564 break;
503 case "close-dialog": 565 case "close-dialog":
504 closeDialog(); 566 closeDialog();
505 break; 567 break;
506 case "edit-custom-filters": 568 case "edit-custom-filters":
507 editCustomFilters(); 569 customFiltersView("write");
508 break; 570 break;
509 case "edit-domain-exception": 571 case "edit-domain-exception":
510 document.querySelector("#whitelisting .controls").classList 572 document.querySelector("#whitelisting .controls").classList
511 .add("mode-edit"); 573 .add("mode-edit");
512 E("whitelisting-textbox").focus(); 574 E("whitelisting-textbox").focus();
513 break; 575 break;
514 case "import-subscription": { 576 case "import-subscription": {
515 let url = E("blockingList-textbox").value; 577 let url = E("blockingList-textbox").value;
516 addEnableSubscription(url); 578 addEnableSubscription(url);
517 closeDialog(); 579 closeDialog();
(...skipping 21 matching lines...) Expand all
539 text: findParentData(element, "access", false) 601 text: findParentData(element, "access", false)
540 }); 602 });
541 break; 603 break;
542 case "remove-subscription": 604 case "remove-subscription":
543 ext.backgroundPage.sendMessage({ 605 ext.backgroundPage.sendMessage({
544 type: "subscriptions.remove", 606 type: "subscriptions.remove",
545 url: findParentData(element, "access", false) 607 url: findParentData(element, "access", false)
546 }); 608 });
547 break; 609 break;
548 case "save-custom-filters": 610 case "save-custom-filters":
549 sendMessageHandleErrors({ 611 sendMessageHandleErrors({
saroyanm 2017/06/11 15:40:12 I still need to figure out how to get exact filter
saroyanm 2017/06/12 16:44:42 Separate this into another review.
Thomas Greiner 2017/07/07 13:01:08 Acknowledged.
550 type: "filters.importRaw", 612 type: "filters.importRaw",
551 text: E("custom-filters-raw").value, 613 text: E("custom-filters-raw").value,
552 removeExisting: true 614 removeExisting: true
553 }, 615 },
554 () => 616 () =>
555 { 617 {
556 E("custom-filters").classList.remove("mode-edit"); 618 customFiltersView("read");
557 }); 619 });
558 break; 620 break;
559 case "switch-tab": 621 case "switch-tab":
560 let tabId = findParentData(element, "tab", false); 622 let tabId = findParentData(element, "tab", false);
561 switchTab(tabId); 623 switchTab(tabId);
562 break; 624 break;
563 case "toggle-disable-subscription": 625 case "toggle-disable-subscription":
564 ext.backgroundPage.sendMessage({ 626 ext.backgroundPage.sendMessage({
565 type: "subscriptions.toggle", 627 type: "subscriptions.toggle",
566 keepInstalled: true, 628 keepInstalled: true,
(...skipping 25 matching lines...) Expand all
592 break; 654 break;
593 case "update-subscription": 655 case "update-subscription":
594 ext.backgroundPage.sendMessage({ 656 ext.backgroundPage.sendMessage({
595 type: "subscriptions.update", 657 type: "subscriptions.update",
596 url: findParentData(element, "access", false) 658 url: findParentData(element, "access", false)
597 }); 659 });
598 break; 660 break;
599 } 661 }
600 } 662 }
601 663
664 function customFiltersView(mode)
665 {
666 switch (mode)
667 {
668 case "read":
669 if (E("custom-filters-box").options.length == 0)
670 {
671 customFiltersView("empty");
672 }
673 else
674 {
675 E("custom-filters").classList.add("mode-view");
676 E("custom-filters").classList.remove("mode-edit");
677 E("custom-filters").classList.remove("mode-empty");
678 }
679 break;
680 case "write":
681 convertToRawFormat();
682 E("custom-filters").classList.remove("mode-view");
683 E("custom-filters").classList.add("mode-edit");
684 E("custom-filters").classList.remove("mode-empty");
685 break;
686 case "empty":
687 E("custom-filters").classList.remove("mode-view");
688 E("custom-filters").classList.remove("mode-edit");
689 E("custom-filters").classList.add("mode-empty");
690 break;
691 }
692 }
693
602 function onClick(e) 694 function onClick(e)
603 { 695 {
604 let context = document.querySelector(".show-context-menu"); 696 let context = document.querySelector(".show-context-menu");
605 if (context) 697 if (context)
606 context.classList.remove("show-context-menu"); 698 context.classList.remove("show-context-menu");
607 699
608 let actions = findParentData(e.target, "action", false); 700 let actions = findParentData(e.target, "action", false);
609 if (!actions) 701 if (!actions)
610 return; 702 return;
611 703
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 previousTab.removeAttribute("aria-selected"); 769 previousTab.removeAttribute("aria-selected");
678 previousTab.setAttribute("tabindex", -1); 770 previousTab.setAttribute("tabindex", -1);
679 771
680 let tab = tabList.querySelector("li[data-tab='" + tabId + "']"); 772 let tab = tabList.querySelector("li[data-tab='" + tabId + "']");
681 tab.setAttribute("aria-selected", true); 773 tab.setAttribute("aria-selected", true);
682 tab.setAttribute("tabindex", 0); 774 tab.setAttribute("tabindex", 0);
683 775
684 let tabContentId = tab.getAttribute("aria-controls"); 776 let tabContentId = tab.getAttribute("aria-controls");
685 let tabContent = document.getElementById(tabContentId); 777 let tabContent = document.getElementById(tabContentId);
686 778
687 // Select sub tabs
688 if (tab.hasAttribute("data-subtab"))
689 selectTabItem(tab.getAttribute("data-subtab"), tabContent, false);
690
691 if (tab && focus) 779 if (tab && focus)
692 tab.focus(); 780 tab.focus();
693 781
694 return tabContent; 782 return tabContent;
695 } 783 }
696 784
697 function onHashChange() 785 function onHashChange()
698 { 786 {
699 let hash = location.hash.substr(1); 787 let hash = location.hash.substr(1);
700 if (!hash) 788 if (!hash)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 let placeholderValue = getMessage("options_dialog_language_find"); 838 let placeholderValue = getMessage("options_dialog_language_find");
751 E("find-language").setAttribute("placeholder", placeholderValue); 839 E("find-language").setAttribute("placeholder", placeholderValue);
752 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); 840 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false);
753 E("whitelisting-textbox").addEventListener("keypress", (e) => 841 E("whitelisting-textbox").addEventListener("keypress", (e) =>
754 { 842 {
755 if (getKey(e) == "Enter") 843 if (getKey(e) == "Enter")
756 addWhitelistedDomain(); 844 addWhitelistedDomain();
757 }, false); 845 }, false);
758 846
759 // Advanced tab 847 // Advanced tab
760 let tweaks = document.querySelectorAll("#tweaks li[data-pref]"); 848 let customize = document.querySelectorAll("#customize li[data-pref]");
761 tweaks = Array.prototype.map.call(tweaks, (checkbox) => 849 customize = Array.prototype.map.call(customize, (checkbox) =>
762 { 850 {
763 return checkbox.getAttribute("data-pref"); 851 return checkbox.getAttribute("data-pref");
764 }); 852 });
765 for (let key of tweaks) 853 for (let key of customize)
766 { 854 {
767 getPref(key, (value) => 855 getPref(key, (value) =>
768 { 856 {
769 onPrefMessage(key, value, true); 857 onPrefMessage(key, value, true);
770 }); 858 });
771 } 859 }
772 ext.backgroundPage.sendMessage({ 860 ext.backgroundPage.sendMessage({
773 type: "app.get", 861 type: "app.get",
774 what: "features" 862 what: "features"
775 }, 863 },
776 (features) => 864 (features) =>
777 { 865 {
778 hidePref("show_devtools_panel", !features.devToolsPanel); 866 hidePref("show_devtools_panel", !features.devToolsPanel);
779 }); 867 });
780 868
781 let filterTextbox = document.querySelector("#custom-filters-add input"); 869 getDocLink("filterdoc", (link) =>
782 placeholderValue = getMessage("options_customFilters_textbox_placeholder");
783 filterTextbox.setAttribute("placeholder", placeholderValue);
784 function addCustomFilters()
785 { 870 {
786 let filterText = filterTextbox.value; 871 E("link-filters").setAttribute("href", link);
787 sendMessageHandleErrors({ 872 });
788 type: "filters.add",
789 text: filterText
790 },
791 () =>
792 {
793 filterTextbox.value = "";
794 });
795 }
796 E("custom-filters-add").addEventListener("submit", (e) =>
797 {
798 e.preventDefault();
799 addCustomFilters();
800 }, false);
801 873
802 // Help tab 874 // Help tab
803 getDocLink("faq", (link) => 875 getDocLink("faq", (link) =>
804 { 876 {
805 E("link-faq").setAttribute("href", link); 877 E("link-faq").setAttribute("href", link);
806 }); 878 });
807 getDocLink("social_twitter", (link) => 879 getDocLink("social_twitter", (link) =>
808 { 880 {
809 E("link-twitter").setAttribute("href", link); 881 E("link-twitter").setAttribute("href", link);
810 }); 882 });
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 { 1089 {
1018 case "added": 1090 case "added":
1019 updateFilter(filter); 1091 updateFilter(filter);
1020 updateShareLink(); 1092 updateShareLink();
1021 break; 1093 break;
1022 case "loaded": 1094 case "loaded":
1023 populateLists(); 1095 populateLists();
1024 break; 1096 break;
1025 case "removed": 1097 case "removed":
1026 let knownFilter = filtersMap[filter.text]; 1098 let knownFilter = filtersMap[filter.text];
1027 collections.whitelist.removeItem(knownFilter); 1099 if (whitelistedDomainRegexp.test(knownFilter.text))
1028 collections.customFilters.removeItem(knownFilter); 1100 collections.whitelist.removeItem(knownFilter);
1101 else
1102 removeCustomFilter(filter.text);
1103
1029 delete filtersMap[filter.text]; 1104 delete filtersMap[filter.text];
1030 updateShareLink(); 1105 updateShareLink();
1031 break; 1106 break;
1032 } 1107 }
1033 } 1108 }
1034 1109
1035 function onSubscriptionMessage(action, subscription) 1110 function onSubscriptionMessage(action, subscription)
1036 { 1111 {
1037 if (subscription.url in subscriptionsMap) 1112 if (subscription.url in subscriptionsMap)
1038 { 1113 {
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 }); 1364 });
1290 ext.backgroundPage.sendMessage({ 1365 ext.backgroundPage.sendMessage({
1291 type: "subscriptions.listen", 1366 type: "subscriptions.listen",
1292 filter: ["added", "disabled", "homepage", "lastDownload", "removed", 1367 filter: ["added", "disabled", "homepage", "lastDownload", "removed",
1293 "title", "downloadStatus", "downloading"] 1368 "title", "downloadStatus", "downloading"]
1294 }); 1369 });
1295 1370
1296 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); 1371 window.addEventListener("DOMContentLoaded", onDOMLoaded, false);
1297 window.addEventListener("hashchange", onHashChange, false); 1372 window.addEventListener("hashchange", onHashChange, false);
1298 } 1373 }
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