| 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 |