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 */ 22 remoting.MenuButton = function(container, opt_onShow) { 23 /** 24 * @type {HTMLElement} 25 * @private 26 */ 27 this.button_ = /** @type {HTMLElement} */ 28 (container.querySelector('button,.menu-button-activator')); 29 30 /** 31 * @type {undefined|function():void} 32 * @private 33 */ 34 this.onShow_ = opt_onShow; 35 36 /** @type {remoting.MenuButton} */ 37 var that = this; 38 39 // Create event handlers to show and hide the menu, attached to the button 40 // and the document <html> tag, respectively. These handlers are added and 41 // removed depending on the state of the menu. To prevent both triggering 42 // for one click, they are added by a timer. 43 /** 44 * @type {function(Event):void} 45 * @private 46 */ 47 this.onClick_ = function(event) { 48 if (that.onShow_) { 49 that.onShow_(); 50 } 51 that.button_.classList.add(remoting.MenuButton.BUTTON_ACTIVE_CLASS_); 52 that.button_.removeEventListener('click', that.onClick_, false); 53 window.setTimeout( 54 function() { 55 // Attach the click handler to the <html> node so that it includes 56 // the document area outside the plugin, which is not covered by 57 // the <body> node. 58 var htmlNode = document.body.parentNode; 59 htmlNode.addEventListener('click', that.closeHandler_, true); 60 }, 61 100); 62 }; 63 64 /** 65 * @type {function(Event):void} 66 * @private 67 */ 68 this.closeHandler_ = function(event) { 69 that.button_.classList.remove(remoting.MenuButton.BUTTON_ACTIVE_CLASS_); 70 document.body.removeEventListener('click', that.closeHandler_, true); 71 window.setTimeout( 72 function() { 73 that.button_.addEventListener('click', that.onClick_, false); 74 }, 75 100); 76 }; 77 78 this.button_.addEventListener('click', this.onClick_, false); 79 }; 80 81 /** 82 * Set or unset the selected state of an <li> menu item. 83 * @param {HTMLElement} item The menu item to update. 84 * @param {boolean} selected True to select the item, false to deselect it. 85 * @return {void} Nothing. 86 */ 87 remoting.MenuButton.select = function(item, selected) { 88 if (selected) { 89 item.classList.add('selected'); 90 } else { 91 item.classList.remove('selected'); 92 } 93 }; 94 95 /** @const @private */ 96 remoting.MenuButton.BUTTON_ACTIVE_CLASS_ = 'active'; 97