Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / remoting / webapp / menu_button.js
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.
4
5 /**
6  * @fileoverview
7  * Class representing a menu button and its associated menu items.
8  */
9
10 'use strict';
11
12 /** @suppress {duplicate} */
13 var remoting = remoting || {};
14
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   /**
26    * @type {HTMLElement}
27    * @private
28    */
29   this.button_ = /** @type {HTMLElement} */
30       (container.querySelector('button,.menu-button-activator'));
31
32   /**
33    * @type {HTMLElement}
34    * @private
35    */
36   this.menu_ = /** @type {HTMLElement} */ (container.querySelector('ul'));
37
38   /**
39    * @type {undefined|function():void}
40    * @private
41    */
42   this.onShow_ = opt_onShow;
43
44   /**
45    * @type {undefined|function():void}
46    * @private
47    */
48   this.onHide_ = opt_onHide;
49
50   /**
51    * Create a "click-trap" div covering the entire document, but below the
52    * menu in the z-order. This ensures the the menu can be closed by clicking
53    * anywhere. Note that adding this event handler to <body> is not enough,
54    * because elements can prevent event propagation; specifically, the client
55    * plugin element does this.
56    *
57    * @type {HTMLElement}
58    * @private
59    */
60   this.clickTrap_ = /** @type {HTMLElement} */ (document.createElement('div'));
61   this.clickTrap_.classList.add('menu-button-click-trap');
62
63   /** @type {remoting.MenuButton} */
64   var that = this;
65
66   var closeHandler = function() {
67     that.button_.classList.remove(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
68     container.removeChild(that.clickTrap_);
69     if (that.onHide_) {
70       that.onHide_();
71     }
72   };
73
74   var onClick = function() {
75     if (that.onShow_) {
76       that.onShow_();
77     }
78     that.button_.classList.add(remoting.MenuButton.BUTTON_ACTIVE_CLASS_);
79     container.appendChild(that.clickTrap_);
80   };
81
82   this.button_.addEventListener('click', onClick, false);
83   this.clickTrap_.addEventListener('click', closeHandler, false);
84   this.menu_.addEventListener('click', closeHandler, false);
85 };
86
87 /**
88  * @return {HTMLElement} The button that activates the menu.
89  */
90 remoting.MenuButton.prototype.button = function() {
91   return this.button_;
92 };
93
94 /**
95  * @return {HTMLElement} The menu.
96  */
97 remoting.MenuButton.prototype.menu = function() {
98   return this.menu_;
99 };
100
101 /**
102  * Set or unset the selected state of an <li> menu item.
103  * @param {Element} item The menu item to update.
104  * @param {boolean} selected True to select the item, false to deselect it.
105  * @return {void} Nothing.
106  */
107 remoting.MenuButton.select = function(item, selected) {
108   if (selected) {
109     /** @type {DOMTokenList} */(item.classList).add('selected');
110   } else {
111     /** @type {DOMTokenList} */(item.classList).remove('selected');
112   }
113 };
114
115 /** @const @private */
116 remoting.MenuButton.BUTTON_ACTIVE_CLASS_ = 'active';