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

Delta Between Two Patch Sets: new-options.js

Issue 29519669: Issue 5539 - Implement "Acceptable Ads notification" (Closed)
Left Patch Set: Created Aug. 18, 2017, 11:51 p.m.
Right Patch Set: Addressed Thomas comment from patchset 6 Created Sept. 22, 2017, 10:28 a.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-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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld