-
Notifications
You must be signed in to change notification settings - Fork 8
/
menu_button.js
116 lines (100 loc) · 3.11 KB
/
menu_button.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
* Class representing a menu button and its associated menu items.
*/
'use strict';
/** @suppress {duplicate} */
var remoting = remoting || {};
/**
* @constructor
* @param {Element} container The element containing the <button> and <ul>
* elements comprising the menu. It should have the "menu-button" class.
* @param {function():void=} opt_onShow Optional callback invoked before the
* menu is shown.
* @param {function():void=} opt_onHide Optional callback after before the
* menu is hidden.
*/
remoting.MenuButton = function(container, opt_onShow, opt_onHide) {
/**
* @type {HTMLElement}
* @private
*/
this.button_ = /** @type {HTMLElement} */
(container.querySelector('button,.menu-button-activator'));
/**
* @type {HTMLElement}
* @private
*/
this.menu_ = /** @type {HTMLElement} */ (container.querySelector('ul'));
/**
* @type {undefined|function():void}
* @private
*/
this.onShow_ = opt_onShow;
/**
* @type {undefined|function():void}
* @private
*/
this.onHide_ = opt_onHide;
/**
* Create a "click-trap" div covering the entire document, but below the
* menu in the z-order. This ensures the the menu can be closed by clicking
* anywhere. Note that adding this event handler to <body> is not enough,
* because elements can prevent event propagation; specifically, the client
* plugin element does this.
*
* @type {HTMLElement}
* @private
*/
this.clickTrap_ = /** @type {HTMLElement} */ (document.createElement('div'));
this.clickTrap_.classList.add('menu-button-click-trap');
/** @type {remoting.MenuButton} */
var that = this;
var closeHandler = function() {
that.button_.classList.remove(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
container.removeChild(that.clickTrap_);
if (that.onHide_) {
that.onHide_();
}
};
var onClick = function() {
if (that.onShow_) {
that.onShow_();
}
that.button_.classList.add(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
container.appendChild(that.clickTrap_);
};
this.button_.addEventListener('click', onClick, false);
this.clickTrap_.addEventListener('click', closeHandler, false);
this.menu_.addEventListener('click', closeHandler, false);
};
/**
* @return {HTMLElement} The button that activates the menu.
*/
remoting.MenuButton.prototype.button = function() {
return this.button_;
};
/**
* @return {HTMLElement} The menu.
*/
remoting.MenuButton.prototype.menu = function() {
return this.menu_;
};
/**
* Set or unset the selected state of an <li> menu item.
* @param {Element} item The menu item to update.
* @param {boolean} selected True to select the item, false to deselect it.
* @return {void} Nothing.
*/
remoting.MenuButton.select = function(item, selected) {
if (selected) {
item.classList.add('selected');
} else {
item.classList.remove('selected');
}
};
/** @const @private */
remoting.MenuButton.BUTTON_ACTIVE_CLASS_ = 'active';