Home | History | Annotate | Download | only in webapp
      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