| 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-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 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 537 case "edit-domain-exception": | 537 case "edit-domain-exception": |
| 538 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); | 538 document.querySelector("#whitelisting .controls").classList.add("mode- edit"); |
| 539 E("whitelisting-textbox").focus(); | 539 E("whitelisting-textbox").focus(); |
| 540 break; | 540 break; |
| 541 case "import-subscription": | 541 case "import-subscription": |
| 542 var url = E("blockingList-textbox").value; | 542 var url = E("blockingList-textbox").value; |
| 543 addEnableSubscription(url); | 543 addEnableSubscription(url); |
| 544 closeDialog(); | 544 closeDialog(); |
| 545 break; | 545 break; |
| 546 case "open-dialog": | 546 case "open-dialog": |
| 547 var dialog = findParentData(element, "dialog", false); | 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); | 548 openDialog(dialog); |
| 549 break; | 549 break; |
| 550 case "open-doclink": | 550 case "open-doclink": |
| 551 var doclink = findParentData(element, "doclink", false); | 551 var doclink = findParentData(element, "doclink", false); |
| 552 openDocLink(doclink); | 552 openDocLink(doclink); |
| 553 break; | 553 break; |
| 554 case "save-custom-filters": | 554 case "save-custom-filters": |
| 555 sendMessageHandleErrors( | 555 sendMessageHandleErrors( |
| 556 { | 556 { |
| 557 type: "filters.importRaw", | 557 type: "filters.importRaw", |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 27: "Escape", | 646 27: "Escape", |
| 647 37: "ArrowLeft", | 647 37: "ArrowLeft", |
| 648 38: "ArrowUp", | 648 38: "ArrowUp", |
| 649 39: "ArrowRight", | 649 39: "ArrowRight", |
| 650 40: "ArrowDown" | 650 40: "ArrowDown" |
| 651 }; | 651 }; |
| 652 | 652 |
| 653 function onKeyUp(e) | 653 function onKeyUp(e) |
| 654 { | 654 { |
| 655 var key = getKey(e); | 655 var key = getKey(e); |
| 656 var element = document.querySelector(":focus"); | 656 var element = document.activeElement; |
|
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) | 657 if (!key || !element) |
| 658 return; | 658 return; |
| 659 | 659 |
| 660 var container = findParentData(element, "action", true); | 660 var container = findParentData(element, "action", true); |
| 661 if (!container || !container.hasAttribute("data-keys")) | 661 if (!container || !container.hasAttribute("data-keys")) |
| 662 return; | 662 return; |
| 663 | 663 |
| 664 var keys = container.getAttribute("data-keys").split(" "); | 664 var keys = container.getAttribute("data-keys").split(" "); |
| 665 if (keys.indexOf(key) < 0) | 665 if (keys.indexOf(key) < 0) |
| 666 return; | 666 return; |
| 667 | 667 |
| 668 switch (container.getAttribute("data-action")) | 668 switch (container.getAttribute("data-action")) |
| 669 { | 669 { |
| 670 case "add-domain-exception": | 670 case "add-domain-exception": |
| 671 addWhitelistedDomain(); | 671 addWhitelistedDomain(); |
| 672 break; | 672 break; |
| 673 case "open-doclink": | 673 case "open-doclink": |
| 674 var doclink = findParentData(element, "doclink", false); | 674 var doclink = findParentData(element, "doclink", false); |
| 675 openDocLink(doclink); | 675 openDocLink(doclink); |
| 676 break; | 676 break; |
| 677 case "switch-tab": | 677 case "switch-tab": |
| 678 if (key == "Enter") | 678 if (key == "Enter") |
| 679 { | 679 { |
| 680 var tabId = findParentData(element, "tab", false); | 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); | 681 switchTab(tabId); |
| 682 } | 682 } |
| 683 else if (element.hasAttribute("aria-selected")) | 683 else if (element.hasAttribute("aria-selected")) |
| 684 { | 684 { |
| 685 if (key == "ArrowLeft" || key == "ArrowUp") | 685 if (key == "ArrowLeft" || key == "ArrowUp") |
| 686 { | 686 { |
| 687 element = element.previousElementSibling | 687 element = element.previousElementSibling |
| 688 || container.lastElementChild; | 688 || container.lastElementChild; |
| 689 } | 689 } |
| 690 else if (key == "ArrowRight" || key == "ArrowDown") | 690 else if (key == "ArrowRight" || key == "ArrowDown") |
| 691 { | 691 { |
| 692 element = element.nextElementSibling | 692 element = element.nextElementSibling |
| 693 || container.firstElementChild; | 693 || container.firstElementChild; |
| 694 } | 694 } |
| 695 | 695 |
| 696 var tabId = findParentData(element, "tab", false); | 696 var tabId = findParentData(element, "tab", false); |
| 697 switchTab(tabId); | 697 switchTab(tabId); |
| 698 } | 698 } |
| 699 break; | 699 break; |
| 700 } | 700 } |
| 701 } | 701 } |
| 702 | 702 |
| 703 function selectTabItem(tabId, container, focus) | |
| 704 { | |
| 705 // Show tab content | |
| 706 document.body.setAttribute("data-tab", tabId); | |
| 707 | |
| 708 // Select tab | |
| 709 var tabList = container.querySelector("[role='tablist']"); | |
| 710 if (!tabList) | |
| 711 return null; | |
| 712 | |
| 713 var previousTab = tabList.querySelector("[aria-selected]"); | |
| 714 previousTab.removeAttribute("aria-selected"); | |
| 715 previousTab.setAttribute("tabindex", -1); | |
| 716 | |
| 717 var tab = tabList.querySelector("li[data-tab='" + tabId + "']"); | |
| 718 tab.setAttribute("aria-selected", true); | |
| 719 tab.setAttribute("tabindex", 0); | |
| 720 | |
| 721 var tabContentId = tab.getAttribute("aria-controls"); | |
| 722 var tabContent = document.getElementById(tabContentId); | |
| 723 | |
| 724 // Select sub tabs | |
| 725 if (tab.hasAttribute("data-subtab")) | |
| 726 selectTabItem(tab.getAttribute("data-subtab"), tabContent, false); | |
| 727 | |
| 728 if (tab && focus) | |
| 729 tab.focus(); | |
| 730 | |
| 731 return tabContent; | |
| 732 } | |
| 733 | |
| 703 function onHashChange() | 734 function onHashChange() |
| 704 { | 735 { |
| 705 var hash = location.hash.substr(1); | 736 var hash = location.hash.substr(1); |
| 706 if (!hash) | 737 if (!hash) |
| 707 return; | 738 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 | 739 |
| 740 // Select tab and parent tabs | 740 // Select tab and parent tabs |
| 741 var tabIds = hash.split("-"); | 741 var tabIds = hash.split("-"); |
| 742 var tabContent = document.body; | 742 var tabContent = document.body; |
| 743 for (var i = 0; i < tabIds.length; i++) | 743 for (var i = 0; i < tabIds.length; i++) |
| 744 { | 744 { |
| 745 var tabId = tabIds.slice(0, i + 1).join("-"); | 745 var tabId = tabIds.slice(0, i + 1).join("-"); |
| 746 tabContent = selectTab(tabId, tabContent, true); | 746 tabContent = selectTabItem(tabId, tabContent, true); |
| 747 if (!tabContent) | 747 if (!tabContent) |
| 748 break; | 748 break; |
| 749 } | 749 } |
| 750 } | 750 } |
| 751 | 751 |
| 752 function onDOMLoaded() | 752 function onDOMLoaded() |
| 753 { | 753 { |
| 754 populateLists(); | 754 populateLists(); |
| 755 function onFindLanguageKeyUp() | 755 function onFindLanguageKeyUp() |
| 756 { | 756 { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 774 getDocLink("releases", function(link) | 774 getDocLink("releases", function(link) |
| 775 { | 775 { |
| 776 E("link-version").setAttribute("href", link); | 776 E("link-version").setAttribute("href", link); |
| 777 }); | 777 }); |
| 778 | 778 |
| 779 updateShareLink(); | 779 updateShareLink(); |
| 780 updateTooltips(); | 780 updateTooltips(); |
| 781 | 781 |
| 782 // Initialize interactive UI elements | 782 // Initialize interactive UI elements |
| 783 document.body.addEventListener("click", onClick, false); | 783 document.body.addEventListener("click", onClick, false); |
| 784 document.body.addEventListener("keyup", onKeyUp, false); | |
| 784 var placeholderValue = getMessage("options_dialog_language_find"); | 785 var placeholderValue = getMessage("options_dialog_language_find"); |
| 785 E("find-language").setAttribute("placeholder", placeholderValue); | 786 E("find-language").setAttribute("placeholder", placeholderValue); |
| 786 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); | 787 E("find-language").addEventListener("keyup", onFindLanguageKeyUp, false); |
| 787 E("whitelisting-textbox").addEventListener("keypress", function(e) | 788 E("whitelisting-textbox").addEventListener("keypress", function(e) |
| 788 { | 789 { |
| 789 if (getKey(e) == "Enter") | 790 if (getKey(e) == "Enter") |
| 790 addWhitelistedDomain(); | 791 addWhitelistedDomain(); |
| 791 }, false); | 792 }, false); |
| 792 | 793 |
| 793 // Advanced tab | 794 // Advanced tab |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 862 } | 863 } |
| 863 else if (e.target.classList.contains("focus-last")) | 864 else if (e.target.classList.contains("focus-last")) |
| 864 { | 865 { |
| 865 e.preventDefault(); | 866 e.preventDefault(); |
| 866 this.querySelector(".focus-first").focus(); | 867 this.querySelector(".focus-first").focus(); |
| 867 } | 868 } |
| 868 break; | 869 break; |
| 869 } | 870 } |
| 870 }, false); | 871 }, false); |
| 871 | 872 |
| 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(); | 873 onHashChange(); |
| 874 } | 874 } |
| 875 | 875 |
| 876 var focusedBeforeDialog = null; | 876 var focusedBeforeDialog = null; |
| 877 function openDialog(name) | 877 function openDialog(name) |
| 878 { | 878 { |
| 879 var dialog = E("dialog"); | 879 var dialog = E("dialog"); |
| 880 dialog.setAttribute("aria-hidden", false); | 880 dialog.setAttribute("aria-hidden", false); |
| 881 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); | 881 dialog.setAttribute("aria-labelledby", "dialog-title-" + name); |
| 882 document.body.setAttribute("data-dialog", name); | 882 document.body.setAttribute("data-dialog", name); |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1281 ext.backgroundPage.sendMessage( | 1281 ext.backgroundPage.sendMessage( |
| 1282 { | 1282 { |
| 1283 type: "subscriptions.listen", | 1283 type: "subscriptions.listen", |
| 1284 filter: ["added", "disabled", "homepage", "lastDownload", "removed", | 1284 filter: ["added", "disabled", "homepage", "lastDownload", "removed", |
| 1285 "title", "downloadStatus", "downloading"] | 1285 "title", "downloadStatus", "downloading"] |
| 1286 }); | 1286 }); |
| 1287 | 1287 |
| 1288 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); | 1288 window.addEventListener("DOMContentLoaded", onDOMLoaded, false); |
| 1289 window.addEventListener("hashchange", onHashChange, false); | 1289 window.addEventListener("hashchange", onHashChange, false); |
| 1290 })(); | 1290 })(); |
| LEFT | RIGHT |