Roll src/third_party/WebKit 3529d49:06e8485 (svn 202554:202555)
[chromium-blink-merge.git] / remoting / webapp / crd / js / menu_button.js
bloba6bd3cf8bdf49c83976f62a00b21f49d6790eff3
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
3 // found in the LICENSE file.
5 /**
6  * @fileoverview
7  * Class representing a menu button and its associated menu items.
8  */
10 'use strict';
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
15 /**
16  * @constructor
17  * @param {Element} container The element containing the <button> and <ul>
18  *     elements comprising the menu. It should have the "menu-button" class.
19  * @param {function():void=} opt_onShow Optional callback invoked before the
20  *     menu is shown.
21  * @param {function():void=} opt_onHide Optional callback after before the
22  *     menu is hidden.
23  */
24 remoting.MenuButton = function(container, opt_onShow, opt_onHide) {
25   /** @private {HTMLElement} */
26   this.button_ = /** @type {HTMLElement} */
27       (container.querySelector('button,.menu-button-activator'));
29   /** @private {HTMLElement} */
30   this.menu_ = /** @type {HTMLElement} */ (container.querySelector('ul'));
32   /** @private {undefined|function():void} */
33   this.onShow_ = opt_onShow;
35   /** @private {undefined|function():void} */
36   this.onHide_ = opt_onHide;
38   /**
39    * Create a "click-trap" div covering the entire document, but below the
40    * menu in the z-order. This ensures the the menu can be closed by clicking
41    * anywhere. Note that adding this event handler to <body> is not enough,
42    * because elements can prevent event propagation; specifically, the client
43    * plugin element does this.
44    *
45    * @private {HTMLElement}
46    */
47   this.clickTrap_ = /** @type {HTMLElement} */ (document.createElement('div'));
48   this.clickTrap_.classList.add('menu-button-click-trap');
50   /** @type {remoting.MenuButton} */
51   var that = this;
53   var closeHandler = function() {
54     that.button_.classList.remove(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
55     container.removeChild(that.clickTrap_);
56     if (that.onHide_) {
57       that.onHide_();
58     }
59   };
61   var onClick = function() {
62     if (that.onShow_) {
63       that.onShow_();
64     }
65     that.button_.classList.add(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
66     container.appendChild(that.clickTrap_);
67   };
69   this.button_.addEventListener('click', onClick, false);
70   this.clickTrap_.addEventListener('click', closeHandler, false);
71   this.menu_.addEventListener('click', closeHandler, false);
74 /**
75  * @return {HTMLElement} The button that activates the menu.
76  */
77 remoting.MenuButton.prototype.button = function() {
78   return this.button_;
81 /**
82  * @return {HTMLElement} The menu.
83  */
84 remoting.MenuButton.prototype.menu = function() {
85   return this.menu_;
88 /**
89  * Set or unset the selected state of an <li> menu item.
90  * @param {Element} item The menu item to update.
91  * @param {boolean} selected True to select the item, false to deselect it.
92  * @return {void} Nothing.
93  */
94 remoting.MenuButton.select = function(item, selected) {
95   if (selected) {
96     item.classList.add('selected');
97   } else {
98     item.classList.remove('selected');
99   }
102 /** @const @private */
103 remoting.MenuButton.BUTTON_ACTIVE_CLASS_ = 'active';