Left: | ||
Right: |
OLD | NEW |
---|---|
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-2016 Eyeo GmbH | 3 * Copyright (C) 2006-2016 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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
463 { | 463 { |
464 ext.backgroundPage.sendMessage(message, function(errors) | 464 ext.backgroundPage.sendMessage(message, function(errors) |
465 { | 465 { |
466 if (errors.length > 0) | 466 if (errors.length > 0) |
467 alert(errors.join("\n")); | 467 alert(errors.join("\n")); |
468 else if (onSuccess) | 468 else if (onSuccess) |
469 onSuccess(); | 469 onSuccess(); |
470 }); | 470 }); |
471 } | 471 } |
472 | 472 |
473 function openDocLink(id) | |
474 { | |
475 getDocLink(id, function(link) | |
476 { | |
477 if (id == "share-general") | |
478 openSharePopup(link); | |
479 else | |
480 location.href = link; | |
481 }); | |
482 } | |
483 | |
484 function switchTab(id) | |
485 { | |
486 location.hash = id; | |
487 } | |
488 | |
473 function onClick(e) | 489 function onClick(e) |
474 { | 490 { |
475 var context = document.querySelector(".show-context-menu"); | 491 var context = document.querySelector(".show-context-menu"); |
476 if (context) | 492 if (context) |
477 context.classList.remove("show-context-menu"); | 493 context.classList.remove("show-context-menu"); |
478 | 494 |
479 var element = e.target; | 495 var element = e.target; |
480 while (true) | 496 while (true) |
481 { | 497 { |
482 if (!element) | 498 if (!element) |
483 return; | 499 return; |
484 | 500 |
485 if (element.hasAttribute("data-action")) | 501 if (element.hasAttribute("data-action")) |
486 break; | 502 break; |
487 | 503 |
488 element = element.parentElement; | 504 element = element.parentElement; |
489 } | 505 } |
490 | 506 |
507 var element = findParentData(e.target, "action", true); | |
491 var actions = element.getAttribute("data-action").split(","); | 508 var actions = element.getAttribute("data-action").split(","); |
492 for (var i = 0; i < actions.length; i++) | 509 for (var i = 0; i < actions.length; i++) |
493 { | 510 { |
494 switch (actions[i]) | 511 switch (actions[i]) |
495 { | 512 { |
496 case "add-domain-exception": | 513 case "add-domain-exception": |
497 addWhitelistedDomain(); | 514 addWhitelistedDomain(); |
498 break; | 515 break; |
499 case "add-predefined-subscription": | 516 case "add-predefined-subscription": |
500 var dialog = E("dialog-content-predefined"); | 517 var dialog = E("dialog-content-predefined"); |
(...skipping 19 matching lines...) Expand all Loading... | |
520 case "edit-domain-exception": | 537 case "edit-domain-exception": |
521 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); | 538 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); |
522 E("whitelisting-textbox").focus(); | 539 E("whitelisting-textbox").focus(); |
523 break; | 540 break; |
524 case "import-subscription": | 541 case "import-subscription": |
525 var url = E("blockingList-textbox").value; | 542 var url = E("blockingList-textbox").value; |
526 addEnableSubscription(url); | 543 addEnableSubscription(url); |
527 closeDialog(); | 544 closeDialog(); |
528 break; | 545 break; |
529 case "open-dialog": | 546 case "open-dialog": |
530 openDialog(element.getAttribute("data-dialog")); | 547 var dialog = findParentData(element, "dialog", false); |
saroyanm
2016/07/25 17:13:34
Are you assigning element to the variable because
Thomas Greiner
2016/07/26 12:50:49
Yes, that makes it easier to read than for instanc
| |
548 openDialog(dialog); | |
549 break; | |
550 case "open-doclink": | |
551 var doclink = findParentData(element, "doclink", false); | |
552 openDocLink(doclink); | |
531 break; | 553 break; |
532 case "save-custom-filters": | 554 case "save-custom-filters": |
533 sendMessageHandleErrors( | 555 sendMessageHandleErrors( |
534 { | 556 { |
535 type: "filters.importRaw", | 557 type: "filters.importRaw", |
536 text: E("custom-filters-raw").value, | 558 text: E("custom-filters-raw").value, |
537 removeExisting: true | 559 removeExisting: true |
538 }, | 560 }, |
539 function() | 561 function() |
540 { | 562 { |
541 E("custom-filters").classList.remove("mode-edit"); | 563 E("custom-filters").classList.remove("mode-edit"); |
542 }); | 564 }); |
543 break; | 565 break; |
544 case "switch-tab": | 566 case "switch-tab": |
545 document.body.setAttribute("data-tab", | 567 var tabId = findParentData(e.target, "tab", false); |
546 element.getAttribute("data-tab")); | 568 switchTab(tabId); |
547 break; | 569 break; |
548 case "toggle-pref": | 570 case "toggle-pref": |
549 ext.backgroundPage.sendMessage( | 571 ext.backgroundPage.sendMessage( |
550 { | 572 { |
551 type: "prefs.toggle", | 573 type: "prefs.toggle", |
552 key: findParentData(element, "pref", false) | 574 key: findParentData(element, "pref", false) |
553 }); | 575 }); |
554 break; | 576 break; |
555 case "update-all-subscriptions": | 577 case "update-all-subscriptions": |
556 ext.backgroundPage.sendMessage( | 578 ext.backgroundPage.sendMessage( |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
604 ext.backgroundPage.sendMessage( | 626 ext.backgroundPage.sendMessage( |
605 { | 627 { |
606 type: "filters.remove", | 628 type: "filters.remove", |
607 text: findParentData(element, "access", false) | 629 text: findParentData(element, "access", false) |
608 }); | 630 }); |
609 break; | 631 break; |
610 } | 632 } |
611 } | 633 } |
612 } | 634 } |
613 | 635 |
636 function getKey(e) | |
637 { | |
638 // e.keyCode has been deprecated so we attempt to use e.key | |
639 if ("key" in e) | |
640 return e.key; | |
641 return getKey.keys[e.keyCode]; | |
642 } | |
643 getKey.keys = { | |
644 9: "Tab", | |
645 13: "Enter", | |
646 27: "Escape", | |
647 37: "ArrowLeft", | |
648 38: "ArrowUp", | |
649 39: "ArrowRight", | |
650 40: "ArrowDown" | |
651 }; | |
652 | |
653 function onKeyUp(e) | |
654 { | |
655 var key = getKey(e); | |
656 var element = document.querySelector(":focus"); | |
saroyanm
2016/07/25 17:13:34
We probably should be able to use document.activeE
Thomas Greiner
2016/07/26 12:50:49
You're absolutely right! Done.
| |
657 if (!key || !element) | |
658 return; | |
659 | |
660 var container = findParentData(element, "action", true); | |
661 if (!container || !container.hasAttribute("data-keys")) | |
662 return; | |
663 | |
664 var keys = container.getAttribute("data-keys").split(" "); | |
665 if (keys.indexOf(key) < 0) | |
666 return; | |
667 | |
668 switch (container.getAttribute("data-action")) | |
669 { | |
670 case "add-domain-exception": | |
671 addWhitelistedDomain(); | |
672 break; | |
673 case "open-doclink": | |
674 var doclink = findParentData(element, "doclink", false); | |
675 openDocLink(doclink); | |
676 break; | |
677 case "switch-tab": | |
678 if (key == "Enter") | |
679 { | |
680 var tabId = findParentData(element, "tab", false); | |
saroyanm
2016/07/25 17:13:34
If I don't miss something this can go outside of i
Thomas Greiner
2016/07/26 12:50:49
`switchTab()` is only called if either Enter is pr
| |
681 switchTab(tabId); | |
682 } | |
683 else if (element.hasAttribute("aria-selected")) | |
684 { | |
685 if (key == "ArrowLeft" || key == "ArrowUp") | |
686 { | |
687 element = element.previousElementSibling | |
688 || container.lastElementChild; | |
689 } | |
690 else if (key == "ArrowRight" || key == "ArrowDown") | |
691 { | |
692 element = element.nextElementSibling | |
693 || container.firstElementChild; | |
694 } | |
695 | |
696 var tabId = findParentData(element, "tab", false); | |
697 switchTab(tabId); | |
698 } | |
699 break; | |
700 } | |
701 } | |
702 | |
703 function onHashChange() | |
704 { | |
705 var hash = location.hash.substr(1); | |
706 if (!hash) | |
707 return; | |
708 | |
709 function selectTab(tabId, container, focus) | |
saroyanm
2016/07/25 17:13:34
This nested function will always recreated on each
Thomas Greiner
2016/07/26 12:50:50
Done.
I wanted to avoid that this function is use
| |
710 { | |
711 // Show tab content | |
712 document.body.setAttribute("data-tab", tabId); | |
713 | |
714 // Select tab | |
715 var tabList = container.querySelector("[role='tablist']"); | |
716 if (!tabList) | |
717 return null; | |
718 | |
719 var previousTab = tabList.querySelector("[aria-selected]"); | |
720 previousTab.removeAttribute("aria-selected"); | |
721 previousTab.setAttribute("tabindex", -1); | |
722 | |
723 var tab = tabList.querySelector("li[data-tab='" + tabId + "']"); | |
724 tab.setAttribute("aria-selected", true); | |
725 tab.setAttribute("tabindex", 0); | |
726 | |
727 var tabContentId = tab.getAttribute("aria-controls"); | |
728 var tabContent = document.getElementById(tabContentId); | |
729 | |
730 // Select sub tabs | |
731 if (tab.hasAttribute("data-subtab")) | |
732 selectTab(tab.getAttribute("data-subtab"), tabContent, false); | |
733 | |
734 if (tab && focus) | |
735 tab.focus(); | |
736 | |
737 return tabContent; | |
738 } | |
739 | |
740 // Select tab and parent tabs | |
741 var tabIds = hash.split("-"); | |
742 var tabContent = document.body; | |
743 for (var i = 0; i < tabIds.length; i++) | |
744 { | |
745 var tabId = tabIds.slice(0, i + 1).join("-"); | |
746 tabContent = selectTab(tabId, tabContent, true); | |
747 if (!tabContent) | |
748 break; | |
749 } | |
750 } | |
751 | |
614 function onDOMLoaded() | 752 function onDOMLoaded() |
615 { | 753 { |
616 populateLists(); | 754 populateLists(); |
617 function onFindLanguageKeyUp() | 755 function onFindLanguageKeyUp() |
618 { | 756 { |
619 var searchStyle = E("search-style"); | 757 var searchStyle = E("search-style"); |
620 if (!this.value) | 758 if (!this.value) |
621 searchStyle.innerHTML = ""; | 759 searchStyle.innerHTML = ""; |
622 else | 760 else |
623 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }"; | 761 searchStyle.innerHTML = "#all-lang-table li:not([data-search*=\"" + this .value.toLowerCase() + "\"]) { display: none; }"; |
624 } | 762 } |
625 | 763 |
626 function getKey(e) | |
627 { | |
628 // e.keyCode has been deprecated so we attempt to use e.key | |
629 if ("key" in e) | |
630 return e.key; | |
631 return getKey.keys[e.keyCode]; | |
632 } | |
633 getKey.keys = { | |
634 9: "Tab", | |
635 13: "Enter", | |
636 27: "Escape" | |
637 }; | |
638 | |
639 // Initialize navigation sidebar | 764 // Initialize navigation sidebar |
640 ext.backgroundPage.sendMessage( | 765 ext.backgroundPage.sendMessage( |
641 { | 766 { |
642 type: "app.get", | 767 type: "app.get", |
643 what: "addonVersion" | 768 what: "addonVersion" |
644 }, | 769 }, |
645 function(addonVersion) | 770 function(addonVersion) |
646 { | 771 { |
647 E("abp-version").textContent = addonVersion; | 772 E("abp-version").textContent = addonVersion; |
648 }); | 773 }); |
649 getDocLink("releases", function(link) | 774 getDocLink("releases", function(link) |
650 { | 775 { |
651 E("link-version").setAttribute("href", link); | 776 E("link-version").setAttribute("href", link); |
652 }); | 777 }); |
653 | 778 |
654 getDocLink("contribute", function(link) | |
655 { | |
656 document.querySelector("#tab-contribute a").setAttribute("href", link); | |
657 }); | |
658 | |
659 updateShareLink(); | 779 updateShareLink(); |
660 updateTooltips(); | 780 updateTooltips(); |
661 | 781 |
662 // Initialize interactive UI elements | 782 // Initialize interactive UI elements |
663 document.body.addEventListener("click", onClick, false); | 783 document.body.addEventListener("click", onClick, false); |
664 var placeholderValue = getMessage("options_dialog_language_find"); | 784 var placeholderValue = getMessage("options_dialog_language_find"); |
665 E("find-language").setAttribute("placeholder", placeholderValue); | 785 E("find-language").setAttribute("placeholder", placeholderValue); |
666 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); | 786 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); |
667 E("whitelisting-textbox").addEventListener("keypress", function(e) | 787 E("whitelisting-textbox").addEventListener("keypress", function(e) |
668 { | 788 { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
741 } | 861 } |
742 } | 862 } |
743 else if (e.target.classList.contains("focus-last")) | 863 else if (e.target.classList.contains("focus-last")) |
744 { | 864 { |
745 e.preventDefault(); | 865 e.preventDefault(); |
746 this.querySelector(".focus-first").focus(); | 866 this.querySelector(".focus-first").focus(); |
747 } | 867 } |
748 break; | 868 break; |
749 } | 869 } |
750 }, false); | 870 }, false); |
871 | |
872 document.body.addEventListener("keyup", onKeyUp, true); | |
saroyanm
2016/07/25 17:13:34
Detail: I think this listener can be defined with
Thomas Greiner
2016/07/26 12:50:49
It's out of place here, I agree. I moved it to the
| |
873 onHashChange(); | |
751 } | 874 } |
752 | 875 |
753 var focusedBeforeDialog = null; | 876 var focusedBeforeDialog = null; |
754 function openDialog(name) | 877 function openDialog(name) |
755 { | 878 { |
756 var dialog = E("dialog"); | 879 var dialog = E("dialog"); |
757 dialog.setAttribute("aria-hidden", false); | 880 dialog.setAttribute("aria-hidden", false); |
758 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); | 881 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); |
759 document.body.setAttribute("data-dialog", name); | 882 document.body.setAttribute("data-dialog", name); |
760 | 883 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
998 case "safari_contentblocker": | 1121 case "safari_contentblocker": |
999 E("restart-safari").setAttribute("aria-hidden", value || initial); | 1122 E("restart-safari").setAttribute("aria-hidden", value || initial); |
1000 break; | 1123 break; |
1001 } | 1124 } |
1002 | 1125 |
1003 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']"); | 1126 var checkbox = document.querySelector("[data-pref='" + key + "'] button[role ='checkbox']"); |
1004 if (checkbox) | 1127 if (checkbox) |
1005 checkbox.setAttribute("aria-checked", value); | 1128 checkbox.setAttribute("aria-checked", value); |
1006 } | 1129 } |
1007 | 1130 |
1008 function onShareLinkClick(e) | |
1009 { | |
1010 e.preventDefault(); | |
1011 | |
1012 getDocLink("share-general", openSharePopup); | |
1013 } | |
1014 | |
1015 function updateShareLink() | 1131 function updateShareLink() |
1016 { | 1132 { |
1017 var shareResources = [ | 1133 var shareResources = [ |
1018 "https://facebook.com/plugins/like.php?", | 1134 "https://facebook.com/plugins/like.php?", |
1019 "https://platform.twitter.com/widgets/", | 1135 "https://platform.twitter.com/widgets/", |
1020 "https://apis.google.com/se/0/_/+1/fastbutton?" | 1136 "https://apis.google.com/se/0/_/+1/fastbutton?" |
1021 ]; | 1137 ]; |
1022 var isAnyBlocked = false; | 1138 var isAnyBlocked = false; |
1023 var checksRemaining = shareResources.length; | 1139 var checksRemaining = shareResources.length; |
1024 | 1140 |
1025 function onResult(isBlocked) | 1141 function onResult(isBlocked) |
1026 { | 1142 { |
1027 isAnyBlocked |= isBlocked; | 1143 isAnyBlocked |= isBlocked; |
1028 if (!--checksRemaining) | 1144 if (!--checksRemaining) |
1029 { | 1145 { |
1030 // Hide the share tab if a script on the share page would be blocked | 1146 // Hide the share tab if a script on the share page would be blocked |
1031 var tab = E("tab-share"); | 1147 E("tab-share").hidden = isAnyBlocked; |
1032 if (isAnyBlocked) | |
1033 { | |
1034 tab.hidden = true; | |
1035 tab.removeEventListener("click", onShareLinkClick, false); | |
1036 } | |
1037 else | |
1038 tab.addEventListener("click", onShareLinkClick, false); | |
1039 } | 1148 } |
1040 } | 1149 } |
1041 | 1150 |
1042 for (var i = 0; i < shareResources.length; i++) | 1151 for (var i = 0; i < shareResources.length; i++) |
1043 checkShareResource(shareResources[i], onResult); | 1152 checkShareResource(shareResources[i], onResult); |
1044 } | 1153 } |
1045 | 1154 |
1046 function getMessages(id) | 1155 function getMessages(id) |
1047 { | 1156 { |
1048 var messages = []; | 1157 var messages = []; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1170 "shouldShowBlockElementMenu"] | 1279 "shouldShowBlockElementMenu"] |
1171 }); | 1280 }); |
1172 ext.backgroundPage.sendMessage( | 1281 ext.backgroundPage.sendMessage( |
1173 { | 1282 { |
1174 type: "subscriptions.listen", | 1283 type: "subscriptions.listen", |
1175 filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 1284 filter: ["added", "disabled", "homepage", "lastDownload", "removed", |
1176 "title", "downloadStatus", "downloading"] | 1285 "title", "downloadStatus", "downloading"] |
1177 }); | 1286 }); |
1178 | 1287 |
1179 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1288 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); |
1289 window.addEventListener("hashchange", onHashChange, false); | |
1180 })(); | 1290 })(); |
OLD | NEW |