OLD | NEW |
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 | 6 |
7 /** @const */ var MenuItem = cr.ui.MenuItem; | 7 /** @const */ var MenuItem = cr.ui.MenuItem; |
8 | 8 |
9 /** | 9 /** |
10 * Creates a new menu element. Menu dispatches all commands on the element it | 10 * Creates a new menu element. Menu dispatches all commands on the element it |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 */ | 70 */ |
71 addSeparator: function() { | 71 addSeparator: function() { |
72 var separator = this.ownerDocument.createElement('hr'); | 72 var separator = this.ownerDocument.createElement('hr'); |
73 cr.ui.decorate(separator, MenuItem); | 73 cr.ui.decorate(separator, MenuItem); |
74 this.appendChild(separator); | 74 this.appendChild(separator); |
75 }, | 75 }, |
76 | 76 |
77 /** | 77 /** |
78 * Clears menu. | 78 * Clears menu. |
79 */ | 79 */ |
80 clear: function() { | 80 clear: function() { this.textContent = ''; }, |
81 this.textContent = ''; | |
82 }, | |
83 | 81 |
84 /** | 82 /** |
85 * Walks up the ancestors of |node| until a menu item belonging to this menu | 83 * Walks up the ancestors of |node| until a menu item belonging to this menu |
86 * is found. | 84 * is found. |
87 * @param {Node} node The node to start searching from. | 85 * @param {Node} node The node to start searching from. |
88 * @return {cr.ui.MenuItem} The found menu item or null. | 86 * @return {cr.ui.MenuItem} The found menu item or null. |
89 * @private | 87 * @private |
90 */ | 88 */ |
91 findMenuItem_: function(node) { | 89 findMenuItem_: function(node) { |
92 while (node && node.parentNode != this && !(node instanceof MenuItem)) { | 90 while (node && node.parentNode != this && !(node instanceof MenuItem)) { |
93 node = node.parentNode; | 91 node = node.parentNode; |
94 } | 92 } |
95 return node ? assertInstanceof(node, MenuItem) : null; | 93 return node ? assertInstanceof(node, MenuItem) : null; |
96 }, | 94 }, |
97 | 95 |
98 /** | 96 /** |
99 * Handles mouseover events and selects the hovered item. | 97 * Handles mouseover events and selects the hovered item. |
100 * @param {Event} e The mouseover event. | 98 * @param {Event} e The mouseover event. |
101 * @private | 99 * @private |
102 */ | 100 */ |
103 handleMouseOver_: function(e) { | 101 handleMouseOver_: function(e) { |
104 var overItem = this.findMenuItem_(/** @type {Element} */(e.target)); | 102 var overItem = this.findMenuItem_(/** @type {Element} */ (e.target)); |
105 this.selectedItem = overItem; | 103 this.selectedItem = overItem; |
106 }, | 104 }, |
107 | 105 |
108 /** | 106 /** |
109 * Handles mouseout events and deselects any selected item. | 107 * Handles mouseout events and deselects any selected item. |
110 * @param {Event} e The mouseout event. | 108 * @param {Event} e The mouseout event. |
111 * @private | 109 * @private |
112 */ | 110 */ |
113 handleMouseOut_: function(e) { | 111 handleMouseOut_: function(e) { this.selectedItem = null; }, |
114 this.selectedItem = null; | |
115 }, | |
116 | 112 |
117 /** | 113 /** |
118 * If there's a mouseup that happens quickly in about the same position, | 114 * If there's a mouseup that happens quickly in about the same position, |
119 * stop it from propagating to items. This is to prevent accidentally | 115 * stop it from propagating to items. This is to prevent accidentally |
120 * selecting a menu item that's created under the mouse cursor. | 116 * selecting a menu item that's created under the mouse cursor. |
121 * @param {Event} e A mouseup event on the menu (in capturing phase). | 117 * @param {Event} e A mouseup event on the menu (in capturing phase). |
122 * @private | 118 * @private |
123 */ | 119 */ |
124 handleMouseUp_: function(e) { | 120 handleMouseUp_: function(e) { |
125 assert(this.contains(/** @type {Element} */(e.target))); | 121 assert(this.contains(/** @type {Element} */ (e.target))); |
126 | 122 |
127 if (!this.trustEvent_(e) || Date.now() - this.shown_.time > 200) | 123 if (!this.trustEvent_(e) || Date.now() - this.shown_.time > 200) |
128 return; | 124 return; |
129 | 125 |
130 var pos = this.shown_.mouseDownPos; | 126 var pos = this.shown_.mouseDownPos; |
131 if (!pos || Math.abs(pos.x - e.screenX) + Math.abs(pos.y - e.screenY) > 4) | 127 if (!pos || Math.abs(pos.x - e.screenX) + Math.abs(pos.y - e.screenY) > 4) |
132 return; | 128 return; |
133 | 129 |
134 e.preventDefault(); | 130 e.preventDefault(); |
135 e.stopPropagation(); | 131 e.stopPropagation(); |
136 }, | 132 }, |
137 | 133 |
138 /** | 134 /** |
139 * @param {!Event} e | 135 * @param {!Event} e |
140 * @return {boolean} Whether |e| can be trusted. | 136 * @return {boolean} Whether |e| can be trusted. |
141 * @private | 137 * @private |
142 * @suppress {checkTypes} | 138 * @suppress {checkTypes} |
143 */ | 139 */ |
144 trustEvent_: function(e) { | 140 trustEvent_: function(e) { return e.isTrusted || e.isTrustedForTesting; }, |
145 return e.isTrusted || e.isTrustedForTesting; | |
146 }, | |
147 | 141 |
148 get menuItems() { | 142 get menuItems() { |
149 return this.querySelectorAll(this.menuItemSelector || '*'); | 143 return this.querySelectorAll(this.menuItemSelector || '*'); |
150 }, | 144 }, |
151 | 145 |
152 /** | 146 /** |
153 * The selected menu item or null if none. | 147 * The selected menu item or null if none. |
154 * @type {cr.ui.MenuItem} | 148 * @type {cr.ui.MenuItem} |
155 */ | 149 */ |
156 get selectedItem() { | 150 get selectedItem() { return this.menuItems[this.selectedIndex]; }, |
157 return this.menuItems[this.selectedIndex]; | |
158 }, | |
159 set selectedItem(item) { | 151 set selectedItem(item) { |
160 var index = Array.prototype.indexOf.call(this.menuItems, item); | 152 var index = Array.prototype.indexOf.call(this.menuItems, item); |
161 this.selectedIndex = index; | 153 this.selectedIndex = index; |
162 }, | 154 }, |
163 | 155 |
164 /** | 156 /** |
165 * Focuses the selected item. If selectedIndex is invalid, set it to 0 | 157 * Focuses the selected item. If selectedIndex is invalid, set it to 0 |
166 * first. | 158 * first. |
167 */ | 159 */ |
168 focusSelectedItem: function() { | 160 focusSelectedItem: function() { |
169 if (this.selectedIndex < 0 || | 161 if (this.selectedIndex < 0 || |
170 this.selectedIndex > this.menuItems.length) { | 162 this.selectedIndex > this.menuItems.length) { |
171 this.selectedIndex = 0; | 163 this.selectedIndex = 0; |
172 } | 164 } |
173 | 165 |
174 if (this.selectedItem) { | 166 if (this.selectedItem) { |
175 this.selectedItem.focus(); | 167 this.selectedItem.focus(); |
176 this.setAttribute('aria-activedescendant', this.selectedItem.id); | 168 this.setAttribute('aria-activedescendant', this.selectedItem.id); |
177 } | 169 } |
178 }, | 170 }, |
179 | 171 |
180 /** | 172 /** |
181 * Menu length | 173 * Menu length |
182 */ | 174 */ |
183 get length() { | 175 get length() { return this.menuItems.length; }, |
184 return this.menuItems.length; | |
185 }, | |
186 | 176 |
187 /** | 177 /** |
188 * Returns if the menu has any visible item. | 178 * Returns if the menu has any visible item. |
189 * @return {boolean} True if the menu has visible item. Otherwise, false. | 179 * @return {boolean} True if the menu has visible item. Otherwise, false. |
190 */ | 180 */ |
191 hasVisibleItems: function() { | 181 hasVisibleItems: function() { |
192 var menuItems = this.menuItems; // Cache. | 182 var menuItems = this.menuItems; // Cache. |
193 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { | 183 for (var i = 0, menuItem; menuItem = menuItems[i]; i++) { |
194 if (!menuItem.hidden) | 184 if (!menuItem.hidden) |
195 return true; | 185 return true; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 } | 293 } |
304 var item = this.selectedItem; | 294 var item = this.selectedItem; |
305 if (item) | 295 if (item) |
306 item.selected = true; | 296 item.selected = true; |
307 } | 297 } |
308 | 298 |
309 /** | 299 /** |
310 * The selected menu item. | 300 * The selected menu item. |
311 * type {number} | 301 * type {number} |
312 */ | 302 */ |
313 cr.defineProperty(Menu, 'selectedIndex', cr.PropertyKind.JS, | 303 cr.defineProperty( |
314 selectedIndexChanged); | 304 Menu, 'selectedIndex', cr.PropertyKind.JS, selectedIndexChanged); |
315 | 305 |
316 /** | 306 /** |
317 * Selector for children which are menu items. | 307 * Selector for children which are menu items. |
318 */ | 308 */ |
319 cr.defineProperty(Menu, 'menuItemSelector', cr.PropertyKind.ATTR); | 309 cr.defineProperty(Menu, 'menuItemSelector', cr.PropertyKind.ATTR); |
320 | 310 |
321 // Export | 311 // Export |
322 return { | 312 return {Menu: Menu}; |
323 Menu: Menu | |
324 }; | |
325 }); | 313 }); |
OLD | NEW |