1// Copyright (c) 2010 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 This implements a special button that is useful for showing a
7 * context menu.
8 */
9
10cr.define('cr.ui', function() {
11  const MenuButton = cr.ui.MenuButton;
12
13  /**
14   * Helper function for ContextMenuButton to find the first ancestor of the
15   * button that has a context menu.
16   * @param {!MenuButton} el The button to start the search from.
17   * @return {HTMLElement} The found element or null if not found.
18   */
19  function getContextMenuTarget(el) {
20    do {
21      el = el.parentNode;
22    } while (el && !('contextMenu' in el));
23    return el;
24  }
25
26  /**
27   * Creates a new menu button which is used to show the context menu for an
28   * ancestor that has a {@code contextMenu} property.
29   * @param {Object=} opt_propertyBag Optional properties.
30   * @constructor
31   * @extends {MenuButton}
32   */
33  var ContextMenuButton = cr.ui.define('button');
34
35  ContextMenuButton.prototype = {
36    __proto__: MenuButton.prototype,
37
38    /**
39     * Override to return the contextMenu for the ancestor.
40     * @override
41     * @type {cr.ui.Menu}
42     */
43    get menu() {
44      var target = getContextMenuTarget(this);
45      return target && target.contextMenu;
46    },
47
48    /** @inheritDoc */
49    decorate: function() {
50      this.tabIndex = -1;
51      this.addEventListener('mouseup', this);
52      MenuButton.prototype.decorate.call(this);
53    },
54
55    /** @inheritDoc */
56    handleEvent: function(e) {
57      switch (e.type) {
58        case 'mousedown':
59          // Menu buttons prevent focus changes.
60          var target = getContextMenuTarget(this);
61          if (target)
62            target.focus();
63          break;
64        case 'mouseup':
65          // Stop mouseup to prevent selection changes.
66          e.stopPropagation();
67          break;
68      }
69      MenuButton.prototype.handleEvent.call(this, e);
70    }
71  };
72
73  // Export
74  return {
75    ContextMenuButton: ContextMenuButton
76  };
77});
78