Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
SeleniumHQ
GitHub Repository: SeleniumHQ/Selenium
Path: blob/trunk/third_party/closure/goog/ui/menuitem.js
4116 views
1
/**
2
* @license
3
* Copyright The Closure Library Authors.
4
* SPDX-License-Identifier: Apache-2.0
5
*/
6
7
/**
8
* @fileoverview A class for representing items in menus.
9
* @see goog.ui.Menu
10
* @see ../demos/menuitem.html
11
*/
12
13
goog.provide('goog.ui.MenuItem');
14
15
goog.require('goog.a11y.aria.Role');
16
goog.require('goog.array');
17
goog.require('goog.dom');
18
goog.require('goog.dom.classlist');
19
goog.require('goog.math.Coordinate');
20
goog.require('goog.string');
21
goog.require('goog.ui.Component');
22
goog.require('goog.ui.Control');
23
goog.require('goog.ui.MenuItemRenderer');
24
goog.require('goog.ui.registry');
25
goog.requireType('goog.events.KeyCodes');
26
goog.requireType('goog.ui.ControlContent'); // circular
27
goog.requireType('goog.ui.Menu');
28
29
30
31
/**
32
* Class representing an item in a menu.
33
*
34
* @param {goog.ui.ControlContent} content Text caption or DOM structure to
35
* display as the content of the item (use to add icons or styling to
36
* menus).
37
* @param {*=} opt_model Data/model associated with the menu item.
38
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper used for
39
* document interactions.
40
* @param {goog.ui.MenuItemRenderer=} opt_renderer Optional renderer.
41
* @constructor
42
* @extends {goog.ui.Control}
43
*/
44
goog.ui.MenuItem = function(content, opt_model, opt_domHelper, opt_renderer) {
45
'use strict';
46
goog.ui.Control.call(
47
this, content, opt_renderer || goog.ui.MenuItemRenderer.getInstance(),
48
opt_domHelper);
49
this.setValue(opt_model);
50
};
51
goog.inherits(goog.ui.MenuItem, goog.ui.Control);
52
53
54
/**
55
* The access key for this menu item. This key allows the user to quickly
56
* trigger this item's action with they keyboard. For example, setting the
57
* mnenomic key to 70 (F), when the user opens the menu and hits "F," the
58
* menu item is triggered.
59
*
60
* @type {goog.events.KeyCodes}
61
* @private
62
*/
63
goog.ui.MenuItem.prototype.mnemonicKey_;
64
65
66
/**
67
* The class set on an element that contains a parenthetical mnemonic key hint.
68
* Parenthetical hints are added to items in which the mnemonic key is not found
69
* within the menu item's caption itself. For example, if you have a menu item
70
* with the caption "Record," but its mnemonic key is "I", the caption displayed
71
* in the menu will appear as "Record (I)".
72
*
73
* @type {string}
74
* @private
75
*/
76
goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_ =
77
goog.getCssName('goog-menuitem-mnemonic-separator');
78
79
80
/**
81
* The class set on an element that contains a keyboard accelerator hint.
82
* @type {string}
83
*/
84
goog.ui.MenuItem.ACCELERATOR_CLASS = goog.getCssName('goog-menuitem-accel');
85
86
87
// goog.ui.Component and goog.ui.Control implementation.
88
89
90
/**
91
* Returns the value associated with the menu item. The default implementation
92
* returns the model object associated with the item (if any), or its caption.
93
* @return {*} Value associated with the menu item, if any, or its caption.
94
*/
95
goog.ui.MenuItem.prototype.getValue = function() {
96
'use strict';
97
var model = this.getModel();
98
return model != null ? model : this.getCaption();
99
};
100
101
102
/**
103
* Sets the value associated with the menu item. The default implementation
104
* stores the value as the model of the menu item.
105
* @param {*} value Value to be associated with the menu item.
106
*/
107
goog.ui.MenuItem.prototype.setValue = function(value) {
108
'use strict';
109
this.setModel(value);
110
};
111
112
113
/** @override */
114
goog.ui.MenuItem.prototype.setSupportedState = function(state, support) {
115
'use strict';
116
goog.ui.MenuItem.base(this, 'setSupportedState', state, support);
117
switch (state) {
118
case goog.ui.Component.State.SELECTED:
119
this.setSelectableInternal_(support);
120
break;
121
case goog.ui.Component.State.CHECKED:
122
this.setCheckableInternal_(support);
123
break;
124
}
125
};
126
127
128
/**
129
* Sets the menu item to be selectable or not. Set to true for menu items
130
* that represent selectable options.
131
* @param {boolean} selectable Whether the menu item is selectable.
132
*/
133
goog.ui.MenuItem.prototype.setSelectable = function(selectable) {
134
'use strict';
135
this.setSupportedState(goog.ui.Component.State.SELECTED, selectable);
136
};
137
138
139
/**
140
* Sets the menu item to be selectable or not.
141
* @param {boolean} selectable Whether the menu item is selectable.
142
* @private
143
* @suppress {strictMissingProperties} Added to tighten compiler checks
144
*/
145
goog.ui.MenuItem.prototype.setSelectableInternal_ = function(selectable) {
146
'use strict';
147
if (this.isChecked() && !selectable) {
148
this.setChecked(false);
149
}
150
151
var element = this.getElement();
152
if (element) {
153
this.getRenderer().setSelectable(this, element, selectable);
154
}
155
};
156
157
158
/**
159
* Sets the menu item to be checkable or not. Set to true for menu items
160
* that represent checkable options.
161
* @param {boolean} checkable Whether the menu item is checkable.
162
*/
163
goog.ui.MenuItem.prototype.setCheckable = function(checkable) {
164
'use strict';
165
this.setSupportedState(goog.ui.Component.State.CHECKED, checkable);
166
};
167
168
169
/**
170
* Sets the menu item to be checkable or not.
171
* @param {boolean} checkable Whether the menu item is checkable.
172
* @private
173
* @suppress {strictMissingProperties} Added to tighten compiler checks
174
*/
175
goog.ui.MenuItem.prototype.setCheckableInternal_ = function(checkable) {
176
'use strict';
177
var element = this.getElement();
178
if (element) {
179
this.getRenderer().setCheckable(this, element, checkable);
180
}
181
};
182
183
184
/**
185
* Returns the text caption of the component while ignoring accelerators.
186
* @override
187
*/
188
goog.ui.MenuItem.prototype.getCaption = function() {
189
'use strict';
190
var content = this.getContent();
191
if (Array.isArray(content)) {
192
var acceleratorClass = goog.ui.MenuItem.ACCELERATOR_CLASS;
193
var mnemonicWrapClass = goog.ui.MenuItem.MNEMONIC_WRAPPER_CLASS_;
194
var caption =
195
goog.array
196
.map(
197
content,
198
function(node) {
199
'use strict';
200
if (goog.dom.isElement(node) &&
201
(goog.dom.classlist.contains(
202
/** @type {!Element} */ (node), acceleratorClass) ||
203
goog.dom.classlist.contains(
204
/** @type {!Element} */ (node),
205
mnemonicWrapClass))) {
206
return '';
207
} else {
208
return goog.dom.getRawTextContent(node);
209
}
210
})
211
.join('');
212
return goog.string.collapseBreakingSpaces(caption);
213
}
214
return goog.ui.MenuItem.superClass_.getCaption.call(this);
215
};
216
217
218
/**
219
* @return {?string} The keyboard accelerator text, or null if the menu item
220
* doesn't have one.
221
*/
222
goog.ui.MenuItem.prototype.getAccelerator = function() {
223
'use strict';
224
var dom = this.getDomHelper();
225
var content = this.getContent();
226
if (Array.isArray(content)) {
227
var acceleratorEl = goog.array.find(content, function(e) {
228
'use strict';
229
return goog.dom.classlist.contains(
230
/** @type {!Element} */ (e), goog.ui.MenuItem.ACCELERATOR_CLASS);
231
});
232
if (acceleratorEl) {
233
return dom.getTextContent(acceleratorEl);
234
}
235
}
236
return null;
237
};
238
239
240
/** @override */
241
goog.ui.MenuItem.prototype.handleMouseUp = function(e) {
242
'use strict';
243
var parentMenu = /** @type {goog.ui.Menu} */ (this.getParent());
244
245
if (parentMenu) {
246
var oldCoords = parentMenu.openingCoords;
247
// Clear out the saved opening coords immediately so they're not used twice.
248
parentMenu.openingCoords = null;
249
250
if (oldCoords && typeof e.clientX === 'number') {
251
/**
252
* @suppress {strictMissingProperties} Added to tighten compiler checks
253
*/
254
var newCoords = new goog.math.Coordinate(e.clientX, e.clientY);
255
if (goog.math.Coordinate.equals(oldCoords, newCoords)) {
256
// This menu was opened by a mousedown and we're handling the consequent
257
// mouseup. The coords haven't changed, meaning this was a simple click,
258
// not a click and drag. Don't do the usual behavior because the menu
259
// just popped up under the mouse and the user didn't mean to activate
260
// this item.
261
return;
262
}
263
}
264
}
265
266
goog.ui.MenuItem.base(this, 'handleMouseUp', e);
267
};
268
269
270
/** @override */
271
goog.ui.MenuItem.prototype.handleKeyEventInternal = function(e) {
272
'use strict';
273
if (e.keyCode == this.getMnemonic() && this.performActionInternal(e)) {
274
return true;
275
} else {
276
return goog.ui.MenuItem.base(this, 'handleKeyEventInternal', e);
277
}
278
};
279
280
281
/**
282
* Sets the mnemonic key code. The mnemonic is the key associated with this
283
* action.
284
* @param {goog.events.KeyCodes} key The key code.
285
*/
286
goog.ui.MenuItem.prototype.setMnemonic = function(key) {
287
'use strict';
288
this.mnemonicKey_ = key;
289
};
290
291
292
/**
293
* Gets the mnemonic key code. The mnemonic is the key associated with this
294
* action.
295
* @return {goog.events.KeyCodes} The key code of the mnemonic key.
296
*/
297
goog.ui.MenuItem.prototype.getMnemonic = function() {
298
'use strict';
299
return this.mnemonicKey_;
300
};
301
302
303
// Register a decorator factory function for goog.ui.MenuItems.
304
goog.ui.registry.setDecoratorByClassName(
305
goog.ui.MenuItemRenderer.CSS_CLASS, function() {
306
'use strict';
307
// MenuItem defaults to using MenuItemRenderer.
308
return new goog.ui.MenuItem(null);
309
});
310
311
312
/**
313
* @override
314
*/
315
goog.ui.MenuItem.prototype.getPreferredAriaRole = function() {
316
'use strict';
317
if (this.isSupportedState(goog.ui.Component.State.CHECKED)) {
318
return goog.a11y.aria.Role.MENU_ITEM_CHECKBOX;
319
}
320
if (this.isSupportedState(goog.ui.Component.State.SELECTED)) {
321
return goog.a11y.aria.Role.MENU_ITEM_RADIO;
322
}
323
return goog.ui.MenuItem.base(this, 'getPreferredAriaRole');
324
};
325
326
327
/**
328
* @override
329
* @return {goog.ui.Menu}
330
*/
331
goog.ui.MenuItem.prototype.getParent = function() {
332
'use strict';
333
return /** @type {goog.ui.Menu} */ (
334
goog.ui.Control.prototype.getParent.call(this));
335
};
336
337
338
/**
339
* @override
340
* @return {goog.ui.Menu}
341
*/
342
goog.ui.MenuItem.prototype.getParentEventTarget = function() {
343
'use strict';
344
return /** @type {goog.ui.Menu} */ (
345
goog.ui.Control.prototype.getParentEventTarget.call(this));
346
};
347
348