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

Side by Side Diff: chrome/browser/resources/shared/js/cr/ui/menu_button.js

Issue 11013021: Basic keyboard access for recently_closed menu on NTP (re-work). (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Rebase to current version. Created 8 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 cr.define('cr.ui', function() { 5 cr.define('cr.ui', function() {
6 /** @const */ 6 /** @const */
7 var Menu = cr.ui.Menu; 7 var Menu = cr.ui.Menu;
8 /** @const */ 8 /** @const */
9 var positionPopupAroundElement = cr.ui.positionPopupAroundElement; 9 var positionPopupAroundElement = cr.ui.positionPopupAroundElement;
10 10
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 if (e.currentTarget == this.ownerDocument) { 76 if (e.currentTarget == this.ownerDocument) {
77 if (!this.contains(e.target) && !this.menu.contains(e.target)) 77 if (!this.contains(e.target) && !this.menu.contains(e.target))
78 this.hideMenu(); 78 this.hideMenu();
79 else 79 else
80 e.preventDefault(); 80 e.preventDefault();
81 } else { 81 } else {
82 if (this.isMenuShown()) { 82 if (this.isMenuShown()) {
83 this.hideMenu(); 83 this.hideMenu();
84 } else if (e.button == 0) { // Only show the menu when using left 84 } else if (e.button == 0) { // Only show the menu when using left
85 // mouse button. 85 // mouse button.
86 this.showMenu(); 86 this.showMenu(false);
87 // Prevent the button from stealing focus on mousedown. 87 // Prevent the button from stealing focus on mousedown.
88 e.preventDefault(); 88 e.preventDefault();
89 } 89 }
90 } 90 }
91 break; 91 break;
92 case 'keydown': 92 case 'keydown':
93 this.handleKeyDown(e); 93 this.handleKeyDown(e);
94 // If the menu is visible we let it handle all the keyboard events. 94 // If the menu is visible we let it handle all the keyboard events.
95 if (this.isMenuShown() && e.currentTarget == this.ownerDocument) { 95 if (this.isMenuShown() && e.currentTarget == this.ownerDocument) {
96 this.menu.handleKeyDown(e); 96 if (this.menu.handleKeyDown(e)) {
97 e.preventDefault(); 97 e.preventDefault();
98 e.stopPropagation(); 98 e.stopPropagation();
99 }
99 } 100 }
100 break; 101 break;
101 102
103 case 'focus':
Dan Beam 2012/11/12 22:55:03 is there a functional difference between "focus on
aboxhall 2012/11/13 00:49:52 Yep - at the time of blur, the new document.active
104 if (!this.contains(e.target) && !this.menu.contains(e.target))
105 this.hideMenu();
106 break;
107
102 case 'activate': 108 case 'activate':
103 case 'blur':
104 case 'resize': 109 case 'resize':
105 this.hideMenu(); 110 this.hideMenu();
106 break; 111 break;
107 } 112 }
108 }, 113 },
109 114
110 /** 115 /**
111 * Shows the menu. 116 * Shows the menu.
117 * @param {boolean} shouldSetFocus Whether to set focus on the
Dan Beam 2012/11/12 22:55:03 nit: is this boolean optional to pass? i.e. is the
aboxhall 2012/11/13 00:49:52 I agree, and I'm pretty sure I changed all call si
118 * selected menu item.
112 */ 119 */
113 showMenu: function() { 120 showMenu: function(shouldSetFocus) {
114 this.hideMenu(); 121 this.hideMenu();
115 122
116 var event = document.createEvent('UIEvents'); 123 var event = document.createEvent('UIEvents');
117 event.initUIEvent('menushow', true, true, window, null); 124 event.initUIEvent('menushow', true, true, window, null);
118 125
119 if (this.dispatchEvent(event)) { 126 if (this.dispatchEvent(event)) {
120 this.menu.hidden = false; 127 this.menu.hidden = false;
121 128
122 this.setAttribute('menu-shown', ''); 129 this.setAttribute('menu-shown', '');
130 if (shouldSetFocus)
131 this.menu.focusSelectedItem();
123 132
124 // when the menu is shown we steal all keyboard events. 133 // when the menu is shown we steal all keyboard events.
125 var doc = this.ownerDocument; 134 var doc = this.ownerDocument;
126 var win = doc.defaultView; 135 var win = doc.defaultView;
127 this.showingEvents_.add(doc, 'keydown', this, true); 136 this.showingEvents_.add(doc, 'keydown', this, true);
128 this.showingEvents_.add(doc, 'mousedown', this, true); 137 this.showingEvents_.add(doc, 'mousedown', this, true);
129 this.showingEvents_.add(doc, 'blur', this, true); 138 this.showingEvents_.add(doc, 'focus', this, true);
130 this.showingEvents_.add(win, 'resize', this); 139 this.showingEvents_.add(win, 'resize', this);
131 this.showingEvents_.add(this.menu, 'activate', this); 140 this.showingEvents_.add(this.menu, 'activate', this);
132 this.positionMenu_(); 141 this.positionMenu_();
133 } 142 }
134 }, 143 },
135 144
136 /** 145 /**
137 * Hides the menu. If your menu can go out of scope, make sure to call this 146 * Hides the menu. If your menu can go out of scope, make sure to call this
138 * first. 147 * first.
139 */ 148 */
140 hideMenu: function() { 149 hideMenu: function() {
141 if (!this.isMenuShown()) 150 if (!this.isMenuShown())
142 return; 151 return;
143 152
144 this.removeAttribute('menu-shown'); 153 this.removeAttribute('menu-shown');
145 this.menu.hidden = true; 154 this.menu.hidden = true;
146 155
147 this.showingEvents_.removeAll(); 156 this.showingEvents_.removeAll();
148 this.menu.selectedIndex = -1; 157 this.focus();
149 }, 158 },
150 159
151 /** 160 /**
152 * Whether the menu is shown. 161 * Whether the menu is shown.
153 */ 162 */
154 isMenuShown: function() { 163 isMenuShown: function() {
155 return this.hasAttribute('menu-shown'); 164 return this.hasAttribute('menu-shown');
156 }, 165 },
157 166
158 /** 167 /**
159 * Positions the menu below the menu button. At this point we do not use any 168 * Positions the menu below the menu button. At this point we do not use any
160 * advanced positioning logic to ensure the menu fits in the viewport. 169 * advanced positioning logic to ensure the menu fits in the viewport.
161 * @private 170 * @private
162 */ 171 */
163 positionMenu_: function() { 172 positionMenu_: function() {
164 positionPopupAroundElement(this, this.menu, this.anchorType, 173 positionPopupAroundElement(this, this.menu, this.anchorType,
165 this.invertLeftRight); 174 this.invertLeftRight);
166 }, 175 },
167 176
168 /** 177 /**
169 * Handles the keydown event for the menu button. 178 * Handles the keydown event for the menu button.
170 */ 179 */
171 handleKeyDown: function(e) { 180 handleKeyDown: function(e) {
172 switch (e.keyIdentifier) { 181 switch (e.keyIdentifier) {
173 case 'Down': 182 case 'Down':
174 case 'Up': 183 case 'Up':
175 case 'Enter': 184 case 'Enter':
176 case 'U+0020': // Space 185 case 'U+0020': // Space
177 if (!this.isMenuShown()) 186 if (!this.isMenuShown())
178 this.showMenu(); 187 this.showMenu(true);
179 e.preventDefault(); 188 e.preventDefault();
180 break; 189 break;
181 case 'Esc': 190 case 'Esc':
182 case 'U+001B': // Maybe this is remote desktop playing a prank? 191 case 'U+001B': // Maybe this is remote desktop playing a prank?
192 case 'U+0009': // Tab
183 this.hideMenu(); 193 this.hideMenu();
184 break; 194 break;
185 } 195 }
186 } 196 }
187 }; 197 };
188 198
189 /** 199 /**
190 * Helper for styling a menu button with a drop-down arrow indicator. 200 * Helper for styling a menu button with a drop-down arrow indicator.
191 * Creates a new 2D canvas context and draws a downward-facing arrow into it. 201 * Creates a new 2D canvas context and draws a downward-facing arrow into it.
192 * @param {string} canvasName The name of the canvas. The canvas can be 202 * @param {string} canvasName The name of the canvas. The canvas can be
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, hoverColor); 240 'drop-down-arrow-hover', ARROW_WIDTH, ARROW_HEIGHT, hoverColor);
231 createDropDownArrowCanvas( 241 createDropDownArrowCanvas(
232 'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, activeColor); 242 'drop-down-arrow-active', ARROW_WIDTH, ARROW_HEIGHT, activeColor);
233 }; 243 };
234 244
235 // Export 245 // Export
236 return { 246 return {
237 MenuButton: MenuButton 247 MenuButton: MenuButton
238 }; 248 };
239 }); 249 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698