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