Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(433)

Side by Side Diff: chrome/browser/resources/new_new_tab.js

Issue 147071: Make the options menu keyboard navigatable. Hide the menu when the... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 // Helpers 2 // Helpers
3 3
4 function $(id) { 4 function $(id) {
5 return document.getElementById(id); 5 return document.getElementById(id);
6 } 6 }
7 7
8 // TODO(arv): Remove these when classList is available in HTML5. 8 // TODO(arv): Remove these when classList is available in HTML5.
9 // https://bugs.webkit.org/show_bug.cgi?id=20709 9 // https://bugs.webkit.org/show_bug.cgi?id=20709
10 function hasClass(el, name) { 10 function hasClass(el, name) {
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 afterTransition(function() { 663 afterTransition(function() {
664 removeClass(notificationElement, 'hide'); 664 removeClass(notificationElement, 'hide');
665 }) 665 })
666 }; 666 };
667 addClass(notificationElement, 'show'); 667 addClass(notificationElement, 'show');
668 window.setTimeout(function() { 668 window.setTimeout(function() {
669 removeClass(notificationElement, 'show'); 669 removeClass(notificationElement, 'show');
670 }, 10000); 670 }, 10000);
671 } 671 }
672 672
673 // Options menu 673 var optionMenu = {
Glen Murphy 2009/06/24 17:04:03 Can you add a brief description?
674 // TODO(arv): Keyboard navigation of the menu items. 674 button: $('option-button'),
675 menu: $('option-menu'),
676 handleMouseDown: function(e) {
677 if (this.isMenuShown()) {
678 this.hideMenu();
679 } else {
680 this.showMenu();
681 }
682 },
675 683
676 function showMenu(button, menu) { 684 showMenu: function() {
677 function hide() { 685 this.menu.style.display = 'block';
678 menu.style.display = ''; 686 this.button.focus();
679 menu.removeEventListener('blur', hide);
680 window.removeEventListener('blur', hide);
681 };
682 menu.addEventListener('blur', hide);
683 window.addEventListener('blur', hide);
684 menu.style.display = 'block';
685 menu.focus();
686 }
687 687
688 $('option-button').addEventListener('click', function(e) { 688 if (!this.boundHideMenu_) {
689 showMenu(this, $('option-menu')); 689 this.boundHideMenu_ = bind(this.hideMenu, this);
690 }); 690 this.boundHandleFocus_ = bind(this.handleFocus_, this);
691 }
692 document.addEventListener('focus', this.boundHandleFocus_, true);
693 document.addEventListener('mousedown', this.boundHandleFocus_, true);
694 window.addEventListener('blur', this.boundHideMenu_);
691 695
692 $('option-menu').addEventListener('click', function(e) { 696 this.menu.onmouseover = bind(this.handleMouseOver, this);
693 var section = Section[e.target.getAttribute('section')]; 697 this.menu.onmouseout = bind(this.handleMouseOut, this);
694 var show = e.target.getAttribute('show') == 'true'; 698 this.menu.onmouseup = bind(this.handleMouseUp, this);
695 if (show) { 699 this.button.onkeydown = bind(this.handleKeyDown, this);
696 showSection(section); 700 },
697 } else { 701
698 hideSection(section); 702 hideMenu: function() {
703 this.menu.style.display = 'none';
704 this.setSelectedIndex(-1);
705
706 document.removeEventListener('focus', this.boundHandleFocus_, true);
707 document.removeEventListener('mousedown', this.boundhandleFocus_, true);
708 window.removeEventListener('blur', this.boundHide_);
709 },
710
711 handleFocus_: function(e) {
712 if (!this.menu.contains(e.target) && !this.button.contains(e.target)) {
713 this.hideMenu();
714 }
715 },
716
717 isMenuShown: function() {
718 return this.menu.style.display == 'block';
719 },
720
721 handleMouseOver: function(e) {
722 var el = e.target;
723 var index = Array.prototype.indexOf.call(this.menu.children, el);
724 console.log(el, index);
725 this.setSelectedIndex(index);
726 },
727
728 handleMouseOut: function(e) {
729 this.setSelectedIndex(-1);
730 },
731
732 handleMouseUp: function(e) {
733 var item = this.getSelectedItem();
734 if (item) {
735 this.executeItem(item);
736 }
737 },
738
739 handleKeyDown: function(e) {
740 var item = this.getSelectedItem();
741
742 var self = this;
743 function selectNextVisible(m) {
744 var children = self.menu.children;
745 var len = children.length;
746 var i = self.selectedIndex_;
747 if (i == -1 && m == -1) {
748 // Edge case when we need to go the last item fisrt.
749 i = 0;
750 }
751 while (true) {
752 i = (i + m + len) % len;
753 item = children[i];
754 if (item && item.style.display != 'none') {
755 break;
756 }
757 }
758 if (item) {
759 self.setSelectedIndex(i);
760 }
761 }
762
763 switch (e.keyIdentifier) {
764 case 'Down':
765 if (!this.isMenuShown()) {
766 this.showMenu();
767 }
768 selectNextVisible(1);
769 break;
770 case 'Up':
771 if (!this.isMenuShown()) {
772 this.showMenu();
773 }
774 selectNextVisible(-1);
775 break;
776 case 'Esc':
777 case 'U+001B': // Maybe this is remote desktop playing a prank?
778 this.hideMenu();
779 break;
780 case 'Enter':
781 if (this.isMenuShown()) {
782 if (item) {
783 this.executeItem(item);
784 }
785 } else {
786 this.showMenu();
787 }
788 break;
789 }
790 },
791
792 selectedIndex_: -1,
793 setSelectedIndex: function(i) {
794 if (i != this.selectedIndex_) {
795 var items = this.menu.children;
796 var oldItem = items[this.selectedIndex_];
797 if (oldItem) {
798 oldItem.removeAttribute('selected');
799 }
800 var newItem = items[i];
801 if (newItem) {
802 newItem.setAttribute('selected', 'selected');
803 }
804 this.selectedIndex_ = i;
805 }
806 },
807
808 getSelectedItem: function() {
809 return this.menu.children[this.selectedIndex_] || null;
810 },
811
812 executeItem: function(item) {
813 var section = Section[item.getAttribute('section')];
814 var show = item.getAttribute('show') == 'true';
815 if (show) {
816 showSection(section);
817 } else {
818 hideSection(section);
819 }
820
821 this.hideMenu();
822
823 layoutLowerSections();
824 mostVisited.updateDisplayMode();
825 layoutMostVisited();
826
827 saveShownSections();
828 },
829
830 init: function() {
831 this.button.onmousedown = bind(this.handleMouseDown, this);
832 this.button.onkeydown = bind(this.handleKeyDown, this);
699 } 833 }
834 };
700 835
701 // Hide menu now. 836 optionMenu.init();
702 this.style.display = 'none';
703
704 layoutLowerSections();
705 mostVisited.updateDisplayMode();
706 layoutMostVisited();
707
708 saveShownSections();
709 });
710 837
711 $('most-visited').addEventListener('click', function(e) { 838 $('most-visited').addEventListener('click', function(e) {
712 var target = e.target; 839 var target = e.target;
713 if (hasClass(target, 'pin')) { 840 if (hasClass(target, 'pin')) {
714 mostVisited.togglePinned(mostVisited.getItem(target)); 841 mostVisited.togglePinned(mostVisited.getItem(target));
715 e.preventDefault(); 842 e.preventDefault();
716 } else if (hasClass(target, 'remove')) { 843 } else if (hasClass(target, 'remove')) {
717 mostVisited.blacklist(mostVisited.getItem(target)); 844 mostVisited.blacklist(mostVisited.getItem(target));
718 e.preventDefault(); 845 e.preventDefault();
719 } else if (hasClass(target, 'edit-link')) { 846 } else if (hasClass(target, 'edit-link')) {
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 el.addEventListener('dragover', bind(this.handleDragOver, this)); 1067 el.addEventListener('dragover', bind(this.handleDragOver, this));
941 el.addEventListener('dragleave', bind(this.handleDragLeave, this)); 1068 el.addEventListener('dragleave', bind(this.handleDragLeave, this));
942 el.addEventListener('drop', bind(this.handleDrop, this)); 1069 el.addEventListener('drop', bind(this.handleDrop, this));
943 el.addEventListener('dragend', bind(this.handleDragEnd, this)); 1070 el.addEventListener('dragend', bind(this.handleDragEnd, this));
944 el.addEventListener('drag', bind(this.handleDrag, this)); 1071 el.addEventListener('drag', bind(this.handleDrag, this));
945 el.addEventListener('mousedown', bind(this.handleMouseDown, this)); 1072 el.addEventListener('mousedown', bind(this.handleMouseDown, this));
946 } 1073 }
947 }; 1074 };
948 1075
949 dnd.init(); 1076 dnd.init();
OLDNEW
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698