Left: | ||
Right: |
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-2017 eyeo GmbH | 3 * Copyright (C) 2006-present 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/>. |
16 */ | 16 */ |
17 | 17 |
18 /* globals checkShareResource, getDocLink, i18nFormatDateTime, openSharePopup, | 18 /* globals checkShareResource, getDocLink, i18nFormatDateTime, openSharePopup, |
19 setLinks, E */ | 19 setLinks, E */ |
20 | 20 |
21 "use strict"; | 21 "use strict"; |
22 | 22 |
23 { | 23 { |
24 let subscriptionsMap = Object.create(null); | 24 let subscriptionsMap = Object.create(null); |
25 let filtersMap = Object.create(null); | 25 let filtersMap = Object.create(null); |
26 let collections = Object.create(null); | 26 let collections = Object.create(null); |
27 let acceptableAdsUrl = null; | 27 let acceptableAdsUrl = null; |
28 let acceptableAdsPrivacyUrl = null; | 28 let acceptableAdsPrivacyUrl = null; |
29 let isCustomFiltersLoaded = false; | 29 let isCustomFiltersLoaded = false; |
30 let isSubscriptionsLoaded = false; | |
31 let {getMessage} = ext.i18n; | 30 let {getMessage} = ext.i18n; |
32 let customFilters = []; | 31 let customFilters = []; |
33 let filterErrors = new Map([ | 32 let filterErrors = new Map([ |
34 ["synchronize_invalid_url", | 33 ["synchronize_invalid_url", |
35 "options_filterList_lastDownload_invalidURL"], | 34 "options_filterList_lastDownload_invalidURL"], |
36 ["synchronize_connection_error", | 35 ["synchronize_connection_error", |
37 "options_filterList_lastDownload_connectionError"], | 36 "options_filterList_lastDownload_connectionError"], |
38 ["synchronize_invalid_data", | 37 ["synchronize_invalid_data", |
39 "options_filterList_lastDownload_invalidData"], | 38 "options_filterList_lastDownload_invalidData"], |
40 ["synchronize_checksum_mismatch", | 39 ["synchronize_checksum_mismatch", |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 listItem.setAttribute("role", "section"); | 134 listItem.setAttribute("role", "section"); |
136 | 135 |
137 let tooltip = listItem.querySelector("[data-tooltip]"); | 136 let tooltip = listItem.querySelector("[data-tooltip]"); |
138 if (tooltip) | 137 if (tooltip) |
139 { | 138 { |
140 let tooltipId = tooltip.getAttribute("data-tooltip"); | 139 let tooltipId = tooltip.getAttribute("data-tooltip"); |
141 tooltipId = tooltipId.replace("%value%", item.recommended); | 140 tooltipId = tooltipId.replace("%value%", item.recommended); |
142 if (getMessage(tooltipId)) | 141 if (getMessage(tooltipId)) |
143 { | 142 { |
144 tooltip.setAttribute("data-tooltip", tooltipId); | 143 tooltip.setAttribute("data-tooltip", tooltipId); |
145 } | |
146 else | |
147 { | |
148 tooltip.parentNode.removeChild(tooltip); | |
149 } | 144 } |
150 } | 145 } |
151 | 146 |
152 for (let control of listItem.querySelectorAll(".control")) | 147 for (let control of listItem.querySelectorAll(".control")) |
153 { | 148 { |
154 if (control.hasAttribute("title")) | 149 if (control.hasAttribute("title")) |
155 { | 150 { |
156 let titleValue = getMessage(control.getAttribute("title")); | 151 let titleValue = getMessage(control.getAttribute("title")); |
157 control.setAttribute("title", titleValue); | 152 control.setAttribute("title", titleValue); |
158 } | 153 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 let nextElement = focusables[index]; | 330 let nextElement = focusables[index]; |
336 if (!nextElement) | 331 if (!nextElement) |
337 return false; | 332 return false; |
338 | 333 |
339 nextElement.focus(); | 334 nextElement.focus(); |
340 return true; | 335 return true; |
341 } | 336 } |
342 | 337 |
343 collections.protection = new Collection([ | 338 collections.protection = new Collection([ |
344 { | 339 { |
345 id: "recommend-security-list-table" | 340 id: "recommend-protection-list-table" |
346 } | 341 } |
347 ]); | 342 ]); |
348 collections.langs = new Collection([ | 343 collections.langs = new Collection([ |
349 { | 344 { |
350 id: "blocking-languages-table", | 345 id: "blocking-languages-table", |
351 emptyText: ["options_language_empty"] | 346 emptyText: ["options_language_empty"] |
352 } | 347 } |
353 ]); | 348 ]); |
354 collections.allLangs = new Collection([ | 349 collections.allLangs = new Collection([ |
355 { | 350 { |
356 id: "all-lang-table-add", | 351 id: "all-lang-table-add", |
357 emptyText: ["options_dialog_language_other_empty"] | 352 emptyText: ["options_dialog_language_other_empty"] |
358 } | 353 } |
359 ]); | 354 ]); |
360 collections.custom = new Collection([ | 355 collections.more = new Collection([ |
361 { | 356 { |
362 id: "custom-list-table" | 357 id: "more-list-table" |
363 } | 358 } |
364 ]); | 359 ]); |
365 collections.whitelist = new Collection([ | 360 collections.whitelist = new Collection([ |
366 { | 361 { |
367 id: "whitelisting-table", | 362 id: "whitelisting-table", |
368 emptyText: ["options_whitelist_empty_1", "options_whitelist_empty_2"] | 363 emptyText: ["options_whitelist_empty_1", "options_whitelist_empty_2"] |
369 } | 364 } |
370 ]); | 365 ]); |
371 collections.filterLists = new Collection([ | 366 collections.filterLists = new Collection([ |
372 { | 367 { |
373 id: "all-filter-lists-table", | 368 id: "all-filter-lists-table", |
374 useOriginalTitle: true | 369 useOriginalTitle: true |
375 } | 370 } |
376 ]); | 371 ]); |
377 | 372 |
378 function addSubscription(subscription) | 373 function addSubscription(subscription) |
379 { | 374 { |
375 let {disabled} = subscription; | |
380 let collection = null; | 376 let collection = null; |
381 if (subscription.recommended) | 377 if (subscription.recommended) |
382 { | 378 { |
383 if (subscription.recommended == "ads") | 379 if (subscription.recommended == "ads") |
384 { | 380 { |
385 if (subscription.disabled == false) | 381 if (disabled == false) |
386 collection = collections.langs; | 382 collection = collections.langs; |
387 | 383 |
388 collections.allLangs.addItem(subscription); | 384 collections.allLangs.addItem(subscription); |
389 } | 385 } |
390 else | 386 else |
391 { | 387 { |
392 collection = collections.protection; | 388 collection = collections.protection; |
393 } | 389 } |
394 } | 390 } |
395 else if (!isAcceptableAds(subscription.url)) | 391 else if (!isAcceptableAds(subscription.url) && disabled == false) |
396 { | 392 { |
397 collection = collections.custom; | 393 collection = collections.more; |
398 } | 394 } |
399 | 395 |
400 if (collection) | 396 if (collection) |
401 collection.addItem(subscription); | 397 collection.addItem(subscription); |
402 | 398 |
403 subscriptionsMap[subscription.url] = subscription; | 399 subscriptionsMap[subscription.url] = subscription; |
404 updateTooltips(); | 400 updateTooltips(); |
405 } | 401 } |
406 | 402 |
407 function updateSubscription(subscription) | 403 function updateSubscription(subscription) |
408 { | 404 { |
409 for (let name in collections) | 405 for (let name in collections) |
410 collections[name].updateItem(subscription); | 406 collections[name].updateItem(subscription); |
411 | 407 |
412 if (subscription.recommended == "ads") | 408 if (subscription.recommended == "ads") |
413 { | 409 { |
414 if (subscription.disabled) | 410 if (subscription.disabled) |
415 collections.langs.removeItem(subscription); | 411 collections.langs.removeItem(subscription); |
416 else | 412 else |
417 collections.langs.addItem(subscription); | 413 collections.langs.addItem(subscription); |
418 } | 414 } |
419 else if (!subscription.recommended && !isAcceptableAds(subscription.url)) | 415 else if (!subscription.recommended && !isAcceptableAds(subscription.url)) |
420 { | 416 { |
421 if (subscription.disabled == false) | 417 if (subscription.disabled == false) |
422 { | 418 { |
423 collections.custom.addItem(subscription); | 419 collections.more.addItem(subscription); |
424 updateTooltips(); | 420 updateTooltips(); |
425 } | 421 } |
426 else | 422 else |
427 { | 423 { |
428 collections.custom.removeItem(subscription); | 424 collections.more.removeItem(subscription); |
429 } | 425 } |
430 } | 426 } |
431 } | 427 } |
432 | 428 |
433 function updateFilter(filter) | 429 function updateFilter(filter) |
434 { | 430 { |
435 let match = filter.text.match(whitelistedDomainRegexp); | 431 let match = filter.text.match(whitelistedDomainRegexp); |
436 if (match && !filtersMap[filter.text]) | 432 if (match && !filtersMap[filter.text]) |
437 { | 433 { |
438 filter.title = match[1]; | 434 filter.title = match[1]; |
439 collections.whitelist.addItem(filter); | 435 collections.whitelist.addItem(filter); |
436 if (isCustomFiltersLoaded) | |
437 { | |
438 let text = getMessage("options_whitelist_notification", [filter.title]); | |
439 showNotification(text); | |
440 } | |
440 } | 441 } |
441 else | 442 else |
442 { | 443 { |
443 customFilters.push(filter.text); | 444 customFilters.push(filter.text); |
444 if (isCustomFiltersLoaded) | 445 if (isCustomFiltersLoaded) |
445 updateCustomFiltersUi(); | 446 updateCustomFiltersUi(); |
446 } | 447 } |
447 | 448 |
448 filtersMap[filter.text] = filter; | 449 filtersMap[filter.text] = filter; |
449 } | 450 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 } | 522 } |
522 | 523 |
523 function sendMessageHandleErrors(message, onSuccess) | 524 function sendMessageHandleErrors(message, onSuccess) |
524 { | 525 { |
525 ext.backgroundPage.sendMessage(message, (errors) => | 526 ext.backgroundPage.sendMessage(message, (errors) => |
526 { | 527 { |
527 if (errors.length > 0) | 528 if (errors.length > 0) |
528 alert(errors.join("\n")); | 529 alert(errors.join("\n")); |
529 else if (onSuccess) | 530 else if (onSuccess) |
530 onSuccess(); | 531 onSuccess(); |
531 }); | |
532 } | |
533 | |
534 function openDocLink(id) | |
535 { | |
536 getDocLink(id, (link) => | |
537 { | |
538 if (id == "share-general") | |
539 openSharePopup(link); | |
540 else | |
541 location.href = link; | |
542 }); | 532 }); |
543 } | 533 } |
544 | 534 |
545 function switchTab(id) | 535 function switchTab(id) |
546 { | 536 { |
547 location.hash = id; | 537 location.hash = id; |
548 } | 538 } |
549 | 539 |
550 function execAction(action, element) | 540 function execAction(action, element) |
551 { | 541 { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 break; | 576 break; |
587 } | 577 } |
588 } | 578 } |
589 break; | 579 break; |
590 case "close-dialog": | 580 case "close-dialog": |
591 closeDialog(); | 581 closeDialog(); |
592 break; | 582 break; |
593 case "edit-custom-filters": | 583 case "edit-custom-filters": |
594 setCustomFiltersView("write"); | 584 setCustomFiltersView("write"); |
595 break; | 585 break; |
586 case "hide-notification": | |
587 hideNotification(); | |
588 break; | |
596 case "import-subscription": { | 589 case "import-subscription": { |
597 let url = E("blockingList-textbox").value; | 590 let url = E("blockingList-textbox").value; |
598 addEnableSubscription(url); | 591 addEnableSubscription(url); |
599 closeDialog(); | 592 closeDialog(); |
600 break; | 593 break; |
601 } | 594 } |
602 case "open-context-menu": { | 595 case "open-context-menu": { |
603 let listItem = findParentData(element, "access", true); | 596 let listItem = findParentData(element, "access", true); |
604 if (listItem && !listItem.classList.contains("show-context-menu")) | 597 if (listItem && !listItem.classList.contains("show-context-menu")) |
605 listItem.classList.add("show-context-menu"); | 598 listItem.classList.add("show-context-menu"); |
606 break; | 599 break; |
607 } | 600 } |
608 case "open-dialog": { | 601 case "open-dialog": { |
609 let dialog = findParentData(element, "dialog", false); | 602 let dialog = findParentData(element, "dialog", false); |
610 openDialog(dialog); | 603 openDialog(dialog); |
611 break; | |
612 } | |
613 case "open-doclink": { | |
614 let doclink = findParentData(element, "doclink", false); | |
615 openDocLink(doclink); | |
616 break; | 604 break; |
617 } | 605 } |
618 case "remove-filter": | 606 case "remove-filter": |
619 ext.backgroundPage.sendMessage({ | 607 ext.backgroundPage.sendMessage({ |
620 type: "filters.remove", | 608 type: "filters.remove", |
621 text: findParentData(element, "access", false) | 609 text: findParentData(element, "access", false) |
622 }); | 610 }); |
623 break; | 611 break; |
624 case "remove-subscription": | 612 case "remove-subscription": |
625 ext.backgroundPage.sendMessage({ | 613 ext.backgroundPage.sendMessage({ |
626 type: "subscriptions.remove", | 614 type: "subscriptions.remove", |
627 url: findParentData(element, "access", false) | 615 url: findParentData(element, "access", false) |
628 }); | 616 }); |
629 break; | 617 break; |
630 case "save-custom-filters": | 618 case "save-custom-filters": |
631 sendMessageHandleErrors({ | 619 sendMessageHandleErrors({ |
632 type: "filters.importRaw", | 620 type: "filters.importRaw", |
633 text: E("custom-filters-raw").value, | 621 text: E("custom-filters-raw").value, |
634 removeExisting: true | 622 removeExisting: true |
635 }, | 623 }, |
636 () => | 624 () => |
637 { | 625 { |
638 setCustomFiltersView("read"); | 626 setCustomFiltersView("read"); |
639 }); | 627 }); |
640 break; | 628 break; |
641 case "switch-acceptable-ads": | 629 case "switch-acceptable-ads": |
642 let value = element.value; | 630 let value = element.value || element.dataset.value; |
643 ext.backgroundPage.sendMessage({ | 631 ext.backgroundPage.sendMessage({ |
644 type: value == "privacy" ? "subscriptions.add" : | 632 type: value == "privacy" ? "subscriptions.add" : |
645 "subscriptions.remove", | 633 "subscriptions.remove", |
646 url: acceptableAdsPrivacyUrl | 634 url: acceptableAdsPrivacyUrl |
647 }); | 635 }); |
648 ext.backgroundPage.sendMessage({ | 636 ext.backgroundPage.sendMessage({ |
649 type: value == "ads" ? "subscriptions.add" : "subscriptions.remove", | 637 type: value == "ads" ? "subscriptions.add" : "subscriptions.remove", |
650 url: acceptableAdsUrl | 638 url: acceptableAdsUrl |
651 }); | 639 }); |
652 break; | 640 break; |
653 case "switch-tab": | 641 case "switch-tab": |
654 let tabId = findParentData(element, "tab", false); | 642 switchTab(element.getAttribute("href").substr(1)); |
655 switchTab(tabId); | |
656 break; | 643 break; |
657 case "toggle-disable-subscription": | 644 case "toggle-disable-subscription": |
658 ext.backgroundPage.sendMessage({ | 645 ext.backgroundPage.sendMessage({ |
659 type: "subscriptions.toggle", | 646 type: "subscriptions.toggle", |
660 keepInstalled: true, | 647 keepInstalled: true, |
661 url: findParentData(element, "access", false) | 648 url: findParentData(element, "access", false) |
662 }); | 649 }); |
663 break; | 650 break; |
664 case "toggle-pref": | 651 case "toggle-pref": |
665 ext.backgroundPage.sendMessage({ | 652 ext.backgroundPage.sendMessage({ |
(...skipping 16 matching lines...) Expand all Loading... | |
682 case "update-all-subscriptions": | 669 case "update-all-subscriptions": |
683 ext.backgroundPage.sendMessage({ | 670 ext.backgroundPage.sendMessage({ |
684 type: "subscriptions.update" | 671 type: "subscriptions.update" |
685 }); | 672 }); |
686 break; | 673 break; |
687 case "update-subscription": | 674 case "update-subscription": |
688 ext.backgroundPage.sendMessage({ | 675 ext.backgroundPage.sendMessage({ |
689 type: "subscriptions.update", | 676 type: "subscriptions.update", |
690 url: findParentData(element, "access", false) | 677 url: findParentData(element, "access", false) |
691 }); | 678 }); |
679 break; | |
680 case "validate-import-subscription": | |
681 let form = findParentData(element, "validation", true); | |
682 if (!form) | |
683 return; | |
684 | |
685 if (form.checkValidity()) | |
686 { | |
687 addEnableSubscription(E("import-list-url").value, | |
688 E("import-list-title").value); | |
689 form.reset(); | |
690 closeDialog(); | |
691 } | |
692 else | |
693 { | |
694 form.querySelector(":invalid").focus(); | |
695 } | |
692 break; | 696 break; |
693 } | 697 } |
694 } | 698 } |
695 | 699 |
696 function setCustomFiltersView(mode) | 700 function setCustomFiltersView(mode) |
697 { | 701 { |
698 let customFiltersElement = E("custom-filters-raw"); | 702 let customFiltersElement = E("custom-filters-raw"); |
699 updateCustomFiltersUi(); | 703 updateCustomFiltersUi(); |
700 if (mode == "read") | 704 if (mode == "read") |
701 { | 705 { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
758 let container = findParentData(element, "action", true); | 762 let container = findParentData(element, "action", true); |
759 if (!container || !container.hasAttribute("data-keys")) | 763 if (!container || !container.hasAttribute("data-keys")) |
760 return; | 764 return; |
761 | 765 |
762 let keys = container.getAttribute("data-keys").split(" "); | 766 let keys = container.getAttribute("data-keys").split(" "); |
763 if (keys.indexOf(key) < 0) | 767 if (keys.indexOf(key) < 0) |
764 return; | 768 return; |
765 | 769 |
766 if (element.getAttribute("role") == "tab") | 770 if (element.getAttribute("role") == "tab") |
767 { | 771 { |
772 let parent = element.parentElement; | |
768 if (key == "ArrowLeft" || key == "ArrowUp") | 773 if (key == "ArrowLeft" || key == "ArrowUp") |
769 element = element.previousElementSibling || container.lastElementChild; | 774 parent = parent.previousElementSibling || container.lastElementChild; |
770 else if (key == "ArrowRight" || key == "ArrowDown") | 775 else if (key == "ArrowRight" || key == "ArrowDown") |
771 element = element.nextElementSibling || container.firstElementChild; | 776 parent = parent.nextElementSibling || container.firstElementChild; |
777 element = parent.firstElementChild; | |
772 } | 778 } |
773 | 779 |
774 let actions = container.getAttribute("data-action").split(","); | 780 let actions = container.getAttribute("data-action").split(","); |
775 for (let action of actions) | 781 for (let action of actions) |
776 { | 782 { |
777 execAction(action, element); | 783 execAction(action, element); |
778 } | 784 } |
779 } | 785 } |
780 | 786 |
781 function selectTabItem(tabId, container, focus) | 787 function selectTabItem(tabId, container, focus) |
782 { | 788 { |
783 // Show tab content | 789 // Show tab content |
784 document.body.setAttribute("data-tab", tabId); | 790 document.body.setAttribute("data-tab", tabId); |
785 | 791 |
786 // Select tab | 792 // Select tab |
787 let tabList = container.querySelector("[role='tablist']"); | 793 let tabList = container.querySelector("[role='tablist']"); |
788 if (!tabList) | 794 if (!tabList) |
789 return null; | 795 return null; |
790 | 796 |
791 let previousTab = tabList.querySelector("[aria-selected]"); | 797 let previousTab = tabList.querySelector("[aria-selected]"); |
792 previousTab.removeAttribute("aria-selected"); | 798 previousTab.removeAttribute("aria-selected"); |
793 previousTab.setAttribute("tabindex", -1); | 799 previousTab.setAttribute("tabindex", -1); |
794 | 800 |
795 let tab = tabList.querySelector("li[data-tab='" + tabId + "']"); | 801 let tab = tabList.querySelector("a[href='#" + tabId + "']"); |
796 tab.setAttribute("aria-selected", true); | 802 tab.setAttribute("aria-selected", true); |
797 tab.setAttribute("tabindex", 0); | 803 tab.setAttribute("tabindex", 0); |
798 | 804 |
799 let tabContentId = tab.getAttribute("aria-controls"); | 805 let tabContentId = tab.getAttribute("aria-controls"); |
800 let tabContent = document.getElementById(tabContentId); | 806 let tabContent = document.getElementById(tabContentId); |
801 | 807 |
802 if (tab && focus) | 808 if (tab && focus) |
803 tab.focus(); | 809 tab.focus(); |
804 | 810 |
805 return tabContent; | 811 return tabContent; |
(...skipping 21 matching lines...) Expand all Loading... | |
827 { | 833 { |
828 populateLists(); | 834 populateLists(); |
829 | 835 |
830 // Initialize navigation sidebar | 836 // Initialize navigation sidebar |
831 ext.backgroundPage.sendMessage({ | 837 ext.backgroundPage.sendMessage({ |
832 type: "app.get", | 838 type: "app.get", |
833 what: "addonVersion" | 839 what: "addonVersion" |
834 }, | 840 }, |
835 (addonVersion) => | 841 (addonVersion) => |
836 { | 842 { |
837 E("abp-version").textContent = addonVersion; | 843 E("abp-version").textContent = getMessage("options_dialog_about_version", |
838 }); | 844 [addonVersion]); |
839 getDocLink("releases", (link) => | 845 }); |
840 { | 846 |
841 E("link-version").setAttribute("href", link); | |
842 }); | |
843 | |
844 updateShareLink(); | |
845 updateTooltips(); | 847 updateTooltips(); |
846 | 848 |
847 // Initialize interactive UI elements | 849 // Initialize interactive UI elements |
848 document.body.addEventListener("click", onClick, false); | 850 document.body.addEventListener("click", onClick, false); |
849 document.body.addEventListener("keyup", onKeyUp, false); | 851 document.body.addEventListener("keyup", onKeyUp, false); |
850 let exampleValue = getMessage("options_whitelist_placeholder_example", | 852 let exampleValue = getMessage("options_whitelist_placeholder_example", |
851 ["www.example.com"]); | 853 ["www.example.com"]); |
852 E("whitelisting-textbox").setAttribute("placeholder", exampleValue); | 854 E("whitelisting-textbox").setAttribute("placeholder", exampleValue); |
853 E("whitelisting-textbox").addEventListener("keyup", (e) => | 855 E("whitelisting-textbox").addEventListener("keyup", (e) => |
854 { | 856 { |
855 E("whitelisting-add-button").disabled = !e.target.value; | 857 E("whitelisting-add-button").disabled = !e.target.value; |
856 }, false); | 858 }, false); |
857 | 859 |
860 getDocLink("contribute", (link) => | |
861 { | |
862 E("contribute").href = link; | |
863 }); | |
858 getDocLink("acceptable_ads_criteria", (link) => | 864 getDocLink("acceptable_ads_criteria", (link) => |
859 { | 865 { |
860 setLinks("enable-aa-description", link); | 866 setLinks("enable-aa-description", link); |
861 }); | 867 }); |
862 | 868 |
863 // Advanced tab | 869 // Advanced tab |
864 let customize = document.querySelectorAll("#customize li[data-pref]"); | 870 let customize = document.querySelectorAll("#customize li[data-pref]"); |
865 customize = Array.prototype.map.call(customize, (checkbox) => | 871 customize = Array.prototype.map.call(customize, (checkbox) => |
866 { | 872 { |
867 return checkbox.getAttribute("data-pref"); | 873 return checkbox.getAttribute("data-pref"); |
(...skipping 21 matching lines...) Expand all Loading... | |
889 | 895 |
890 getDocLink("subscriptions", (link) => | 896 getDocLink("subscriptions", (link) => |
891 { | 897 { |
892 setLinks("filter-lists-description", link); | 898 setLinks("filter-lists-description", link); |
893 }); | 899 }); |
894 | 900 |
895 E("custom-filters-raw").setAttribute("placeholder", | 901 E("custom-filters-raw").setAttribute("placeholder", |
896 getMessage("options_customFilters_edit_placeholder", ["/ads/track/*"])); | 902 getMessage("options_customFilters_edit_placeholder", ["/ads/track/*"])); |
897 | 903 |
898 // Help tab | 904 // Help tab |
899 getDocLink("faq", (link) => | 905 getDocLink("adblock_plus_report_issue", (link) => |
900 { | 906 { |
901 E("link-faq").setAttribute("href", link); | 907 setLinks("report-issue", link); |
908 }); | |
909 getDocLink("adblock_plus_report_ad", (link) => | |
910 { | |
911 setLinks("report-ad", link); | |
912 }); | |
913 getDocLink("adblock_plus_report_bug", (link) => | |
914 { | |
915 setLinks("report-bug", link); | |
916 }); | |
917 getDocLink("reporter_other_link", (link) => | |
918 { | |
919 setLinks("report-forum", link); | |
902 }); | 920 }); |
903 getDocLink("social_twitter", (link) => | 921 getDocLink("social_twitter", (link) => |
904 { | 922 { |
905 E("link-twitter").setAttribute("href", link); | 923 E("twitter").setAttribute("href", link); |
906 }); | 924 }); |
907 getDocLink("social_facebook", (link) => | 925 getDocLink("social_facebook", (link) => |
908 { | 926 { |
909 E("link-facebook").setAttribute("href", link); | 927 E("facebook").setAttribute("href", link); |
910 }); | 928 }); |
911 getDocLink("social_gplus", (link) => | 929 getDocLink("social_gplus", (link) => |
912 { | 930 { |
913 E("link-gplus").setAttribute("href", link); | 931 E("google-plus").setAttribute("href", link); |
914 }); | |
915 getDocLink("social_renren", (link) => | |
916 { | |
917 E("link-renren").setAttribute("href", link); | |
918 }); | 932 }); |
919 getDocLink("social_weibo", (link) => | 933 getDocLink("social_weibo", (link) => |
920 { | 934 { |
921 E("link-weibo").setAttribute("href", link); | 935 E("weibo").setAttribute("href", link); |
922 }); | |
923 | |
924 // Set forum link | |
925 ext.backgroundPage.sendMessage({ | |
926 type: "app.get", | |
927 what: "platform" | |
928 }, | |
929 (platform) => | |
930 { | |
931 ext.backgroundPage.sendMessage({ | |
932 type: "app.get", | |
933 what: "application" | |
934 }, | |
935 (application) => | |
936 { | |
937 if (platform == "chromium" && application != "opera") | |
938 application = "chrome"; | |
939 | |
940 getDocLink(application + "_support", (link) => | |
941 { | |
942 E("link-forum").setAttribute("href", link); | |
943 }); | |
944 }); | |
945 }); | 936 }); |
946 | 937 |
947 E("dialog").addEventListener("keydown", function(e) | 938 E("dialog").addEventListener("keydown", function(e) |
948 { | 939 { |
949 switch (getKey(e)) | 940 switch (getKey(e)) |
950 { | 941 { |
951 case "Escape": | 942 case "Escape": |
952 closeDialog(); | 943 closeDialog(); |
953 break; | 944 break; |
954 case "Tab": | 945 case "Tab": |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
991 | 982 |
992 function closeDialog() | 983 function closeDialog() |
993 { | 984 { |
994 let dialog = E("dialog"); | 985 let dialog = E("dialog"); |
995 dialog.setAttribute("aria-hidden", true); | 986 dialog.setAttribute("aria-hidden", true); |
996 dialog.removeAttribute("aria-labelledby"); | 987 dialog.removeAttribute("aria-labelledby"); |
997 document.body.removeAttribute("data-dialog"); | 988 document.body.removeAttribute("data-dialog"); |
998 focusedBeforeDialog.focus(); | 989 focusedBeforeDialog.focus(); |
999 } | 990 } |
1000 | 991 |
1001 function setDntNotification(state) | 992 function showNotification(text) |
1002 { | 993 { |
1003 if (state) | 994 E("notification").setAttribute("aria-hidden", false); |
1004 E("acceptable-ads").classList.add("show-dnt-notification"); | 995 E("notification-text").textContent = text; |
1005 else | 996 setTimeout(hideNotification, 3000); |
1006 E("acceptable-ads").classList.remove("show-dnt-notification"); | 997 } |
998 | |
999 function hideNotification() | |
1000 { | |
1001 E("notification").setAttribute("aria-hidden", true); | |
1002 E("notification-text").textContent = ""; | |
1007 } | 1003 } |
1008 | 1004 |
1009 function setAcceptableAds() | 1005 function setAcceptableAds() |
1010 { | 1006 { |
1011 let optionsContainer = E("acceptable-ads"); | 1007 let option = "none"; |
1012 optionsContainer.querySelector("[value='none']").checked = true; | 1008 document.forms["acceptable-ads"].classList.remove("show-dnt-notification"); |
1013 for (let url in subscriptionsMap) | 1009 if (acceptableAdsUrl in subscriptionsMap) |
1014 { | 1010 { |
1015 if (url == acceptableAdsPrivacyUrl) | 1011 option = "ads"; |
1016 { | 1012 } |
1017 optionsContainer.querySelector("[value='privacy']").checked = true; | 1013 else if (acceptableAdsPrivacyUrl in subscriptionsMap) |
1018 } | 1014 { |
1019 if (url == acceptableAdsUrl) | 1015 option = "privacy"; |
1020 { | 1016 |
1021 optionsContainer.querySelector("[value='ads']").checked = true; | 1017 if (!navigator.doNotTrack) |
1022 break; | 1018 document.forms["acceptable-ads"].classList.add("show-dnt-notification"); |
1023 } | 1019 } |
1024 } | 1020 document.forms["acceptable-ads"]["acceptable-ads"].value = option; |
1025 } | 1021 } |
1026 | 1022 |
1027 function isAcceptableAds(url) | 1023 function isAcceptableAds(url) |
1028 { | 1024 { |
1029 return url == acceptableAdsUrl || url == acceptableAdsPrivacyUrl; | 1025 return url == acceptableAdsUrl || url == acceptableAdsPrivacyUrl; |
1030 } | 1026 } |
1031 | 1027 |
1032 function isPrivacyAndAdsEnabled() | 1028 function hasPrivacyConflict() |
Thomas Greiner
2017/08/25 18:44:52
This function is a bit difficult to understand so
saroyanm
2017/08/27 16:25:28
Agree, thanks.
saroyanm
2017/09/14 21:56:14
Done.
| |
1033 { | 1029 { |
1034 let isAcceptableAds = subscriptionsMap[acceptableAdsUrl]; | 1030 let acceptableAdsList = subscriptionsMap[acceptableAdsUrl]; |
1035 isAcceptableAds = isAcceptableAds && isAcceptableAds.disabled == false; | 1031 let privacyList = null; |
1036 for (let url in subscriptionsMap) | 1032 for (let url in subscriptionsMap) |
1037 { | 1033 { |
1038 let subscription = subscriptionsMap[url]; | 1034 let subscription = subscriptionsMap[url]; |
1039 if (subscription.recommended == "privacy") | 1035 if (subscription.recommended == "privacy") |
1040 return subscription.disabled == false && isAcceptableAds; | 1036 { |
1041 } | 1037 privacyList = subscription; |
1038 break; | |
1039 } | |
1040 } | |
1041 return acceptableAdsList && acceptableAdsList.disabled == false && | |
1042 privacyList && privacyList.disabled == false; | |
1042 } | 1043 } |
1043 | 1044 |
1044 function populateLists() | 1045 function populateLists() |
1045 { | 1046 { |
1046 subscriptionsMap = Object.create(null); | 1047 subscriptionsMap = Object.create(null); |
1047 filtersMap = Object.create(null); | 1048 filtersMap = Object.create(null); |
1048 | 1049 |
1049 // Empty collections and lists | 1050 // Empty collections and lists |
1050 for (let property in collections) | 1051 for (let property in collections) |
1051 collections[property].clearAll(); | 1052 collections[property].clearAll(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1096 | 1097 |
1097 // Load user subscriptions | 1098 // Load user subscriptions |
1098 ext.backgroundPage.sendMessage({ | 1099 ext.backgroundPage.sendMessage({ |
1099 type: "subscriptions.get", | 1100 type: "subscriptions.get", |
1100 downloadable: true | 1101 downloadable: true |
1101 }, | 1102 }, |
1102 (subscriptions) => | 1103 (subscriptions) => |
1103 { | 1104 { |
1104 for (let subscription of subscriptions) | 1105 for (let subscription of subscriptions) |
1105 onSubscriptionMessage("added", subscription); | 1106 onSubscriptionMessage("added", subscription); |
1106 isSubscriptionsLoaded = true; | |
1107 }); | 1107 }); |
1108 }); | 1108 }); |
1109 }); | 1109 }); |
1110 } | 1110 } |
1111 | 1111 |
1112 function addWhitelistedDomain() | 1112 function addWhitelistedDomain() |
1113 { | 1113 { |
1114 let domain = E("whitelisting-textbox"); | 1114 let domain = E("whitelisting-textbox"); |
1115 for (let whitelistItem of collections.whitelist.items) | 1115 for (let whitelistItem of collections.whitelist.items) |
1116 { | 1116 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1155 ext.backgroundPage.sendMessage(message); | 1155 ext.backgroundPage.sendMessage(message); |
1156 } | 1156 } |
1157 | 1157 |
1158 function onFilterMessage(action, filter) | 1158 function onFilterMessage(action, filter) |
1159 { | 1159 { |
1160 switch (action) | 1160 switch (action) |
1161 { | 1161 { |
1162 case "added": | 1162 case "added": |
1163 filter[timestampUI] = Date.now(); | 1163 filter[timestampUI] = Date.now(); |
1164 updateFilter(filter); | 1164 updateFilter(filter); |
1165 updateShareLink(); | |
1166 break; | 1165 break; |
1167 case "loaded": | 1166 case "loaded": |
1168 populateLists(); | 1167 populateLists(); |
1169 break; | 1168 break; |
1170 case "removed": | 1169 case "removed": |
1171 let knownFilter = filtersMap[filter.text]; | 1170 let knownFilter = filtersMap[filter.text]; |
1172 if (whitelistedDomainRegexp.test(knownFilter.text)) | 1171 if (whitelistedDomainRegexp.test(knownFilter.text)) |
1173 collections.whitelist.removeItem(knownFilter); | 1172 collections.whitelist.removeItem(knownFilter); |
1174 else | 1173 else |
1175 removeCustomFilter(filter.text); | 1174 removeCustomFilter(filter.text); |
1176 | 1175 |
1177 delete filtersMap[filter.text]; | 1176 delete filtersMap[filter.text]; |
1178 updateShareLink(); | |
1179 break; | 1177 break; |
1180 } | 1178 } |
1181 } | 1179 } |
1182 | 1180 |
1183 function onSubscriptionMessage(action, subscription) | 1181 function onSubscriptionMessage(action, subscription) |
1184 { | 1182 { |
1185 if (subscription.url in subscriptionsMap) | 1183 if (subscription.url in subscriptionsMap) |
1186 { | 1184 { |
1187 let knownSubscription = subscriptionsMap[subscription.url]; | 1185 let knownSubscription = subscriptionsMap[subscription.url]; |
1188 for (let property in subscription) | 1186 for (let property in subscription) |
(...skipping 11 matching lines...) Expand all Loading... | |
1200 updateSubscription(subscription); | 1198 updateSubscription(subscription); |
1201 break; | 1199 break; |
1202 case "downloading": | 1200 case "downloading": |
1203 case "downloadStatus": | 1201 case "downloadStatus": |
1204 case "homepage": | 1202 case "homepage": |
1205 case "lastDownload": | 1203 case "lastDownload": |
1206 case "title": | 1204 case "title": |
1207 updateSubscription(subscription); | 1205 updateSubscription(subscription); |
1208 break; | 1206 break; |
1209 case "added": | 1207 case "added": |
1210 let url = subscription.url; | 1208 let {url, recommended} = subscription; |
1211 if (url in subscriptionsMap) | 1209 if (url in subscriptionsMap) |
1212 updateSubscription(subscription); | 1210 updateSubscription(subscription); |
1213 else | 1211 else |
1214 addSubscription(subscription); | 1212 addSubscription(subscription); |
1215 | 1213 |
1216 if (isAcceptableAds(url)) | 1214 if (isAcceptableAds(url)) |
1217 setAcceptableAds(); | 1215 setAcceptableAds(); |
1218 | 1216 |
1219 if (url == acceptableAdsPrivacyUrl) | 1217 if ((url == acceptableAdsUrl || recommended == "privacy") && |
1220 { | 1218 hasPrivacyConflict()) |
1221 if (!navigator.doNotTrack) | 1219 { |
1222 setDntNotification(true); | 1220 getPref("ui_warn_tracking", (showTrackingWarning) => |
1223 } | 1221 { |
1224 | 1222 if (showTrackingWarning) |
1225 if (url == acceptableAdsUrl || subscription.recommended == "privacy") | 1223 openDialog("tracking"); |
1226 { | 1224 }); |
1227 if (isSubscriptionsLoaded && isPrivacyAndAdsEnabled()) | |
Thomas Greiner
2017/08/25 18:44:51
Why is checking for `isSubscriptionsLoaded` necess
saroyanm
2017/08/27 16:25:28
I did it in order not to show on each load of the
Thomas Greiner
2017/08/29 10:20:41
So it's a stopgap solution until we have the prefe
saroyanm
2017/09/14 21:56:14
Done.
| |
1228 openDialog("tracking"); | |
saroyanm
2017/08/19 00:00:40
In specs it says that "This is a one time message"
Thomas Greiner
2017/08/25 18:44:51
Yes. Probably best to prefix the preference name w
saroyanm
2017/08/27 16:25:28
Thanks, I'll have a look into this.
saroyanm
2017/09/14 21:56:14
Done.
| |
1229 } | 1225 } |
1230 | 1226 |
1231 collections.filterLists.addItem(subscription); | 1227 collections.filterLists.addItem(subscription); |
1232 break; | 1228 break; |
1233 case "removed": | 1229 case "removed": |
1234 if (subscription.recommended) | 1230 if (subscription.recommended) |
1235 { | 1231 { |
1236 subscription.disabled = true; | 1232 subscription.disabled = true; |
1237 onSubscriptionMessage("disabled", subscription); | 1233 onSubscriptionMessage("disabled", subscription); |
1238 } | 1234 } |
1239 else if (isAcceptableAds(subscription.url)) | 1235 else |
1240 { | 1236 { |
1241 if (subscription.url == acceptableAdsPrivacyUrl) | 1237 delete subscriptionsMap[subscription.url]; |
1238 if (isAcceptableAds(subscription.url)) | |
1242 { | 1239 { |
1243 setDntNotification(false); | 1240 setAcceptableAds(); |
1244 } | 1241 } |
1245 | 1242 else |
1246 delete subscriptionsMap[subscription.url]; | 1243 { |
1247 setAcceptableAds(); | 1244 collections.more.removeItem(subscription); |
1248 } | 1245 } |
1249 else | |
1250 { | |
1251 collections.custom.removeItem(subscription); | |
1252 delete subscriptionsMap[subscription.url]; | |
1253 } | 1246 } |
1254 collections.filterLists.removeItem(subscription); | 1247 collections.filterLists.removeItem(subscription); |
1255 break; | 1248 break; |
1256 } | 1249 } |
1257 | |
1258 updateShareLink(); | |
1259 } | 1250 } |
1260 | 1251 |
1261 function hidePref(key, value) | 1252 function hidePref(key, value) |
1262 { | 1253 { |
1263 let element = document.querySelector("[data-pref='" + key + "']"); | 1254 let element = document.querySelector("[data-pref='" + key + "']"); |
1264 if (element) | 1255 if (element) |
1265 element.setAttribute("aria-hidden", value); | 1256 element.setAttribute("aria-hidden", value); |
1266 } | 1257 } |
1267 | 1258 |
1268 function getPref(key, callback) | 1259 function getPref(key, callback) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1307 case "notifications_showui": | 1298 case "notifications_showui": |
1308 hidePref("notifications_ignoredcategories", !value); | 1299 hidePref("notifications_ignoredcategories", !value); |
1309 break; | 1300 break; |
1310 } | 1301 } |
1311 | 1302 |
1312 let checkbox = document.querySelector( | 1303 let checkbox = document.querySelector( |
1313 "[data-pref='" + key + "'] button[role='checkbox']" | 1304 "[data-pref='" + key + "'] button[role='checkbox']" |
1314 ); | 1305 ); |
1315 if (checkbox) | 1306 if (checkbox) |
1316 checkbox.setAttribute("aria-checked", value); | 1307 checkbox.setAttribute("aria-checked", value); |
1317 } | |
1318 | |
1319 function updateShareLink() | |
1320 { | |
1321 let shareResources = [ | |
1322 "https://facebook.com/plugins/like.php?", | |
1323 "https://platform.twitter.com/widgets/", | |
1324 "https://apis.google.com/se/0/_/+1/fastbutton?" | |
1325 ]; | |
1326 let isAnyBlocked = false; | |
1327 let checksRemaining = shareResources.length; | |
1328 | |
1329 function onResult(isBlocked) | |
1330 { | |
1331 isAnyBlocked |= isBlocked; | |
1332 if (!--checksRemaining) | |
1333 { | |
1334 // Hide the share tab if a script on the share page would be blocked | |
1335 E("tab-share").hidden = isAnyBlocked; | |
1336 } | |
1337 } | |
1338 | |
1339 for (let sharedResource of shareResources) | |
1340 checkShareResource(sharedResource, onResult); | |
1341 } | 1308 } |
1342 | 1309 |
1343 function updateTooltips() | 1310 function updateTooltips() |
1344 { | 1311 { |
1345 let anchors = document.querySelectorAll(":not(.tooltip) > [data-tooltip]"); | 1312 let anchors = document.querySelectorAll(":not(.tooltip) > [data-tooltip]"); |
1346 for (let anchor of anchors) | 1313 for (let anchor of anchors) |
1347 { | 1314 { |
1348 let id = anchor.getAttribute("data-tooltip"); | 1315 let id = anchor.getAttribute("data-tooltip"); |
1349 | 1316 |
1350 let wrapper = document.createElement("div"); | 1317 let wrapper = document.createElement("div"); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1398 type: "app.listen", | 1365 type: "app.listen", |
1399 filter: ["addSubscription", "focusSection"] | 1366 filter: ["addSubscription", "focusSection"] |
1400 }); | 1367 }); |
1401 ext.backgroundPage.sendMessage({ | 1368 ext.backgroundPage.sendMessage({ |
1402 type: "filters.listen", | 1369 type: "filters.listen", |
1403 filter: ["added", "loaded", "removed"] | 1370 filter: ["added", "loaded", "removed"] |
1404 }); | 1371 }); |
1405 ext.backgroundPage.sendMessage({ | 1372 ext.backgroundPage.sendMessage({ |
1406 type: "prefs.listen", | 1373 type: "prefs.listen", |
1407 filter: ["notifications_ignoredcategories", "notifications_showui", | 1374 filter: ["notifications_ignoredcategories", "notifications_showui", |
1408 "show_devtools_panel", "shouldShowBlockElementMenu"] | 1375 "show_devtools_panel", "shouldShowBlockElementMenu", |
1376 "ui_warn_tracking"] | |
1409 }); | 1377 }); |
1410 ext.backgroundPage.sendMessage({ | 1378 ext.backgroundPage.sendMessage({ |
1411 type: "subscriptions.listen", | 1379 type: "subscriptions.listen", |
1412 filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 1380 filter: ["added", "disabled", "homepage", "lastDownload", "removed", |
1413 "title", "downloadStatus", "downloading"] | 1381 "title", "downloadStatus", "downloading"] |
1414 }); | 1382 }); |
1415 | 1383 |
1416 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1384 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); |
1417 window.addEventListener("hashchange", onHashChange, false); | 1385 window.addEventListener("hashchange", onHashChange, false); |
1418 } | 1386 } |
LEFT | RIGHT |