| Index: resources/bookmark_manager/js/cr/ui/menubutton.js
|
| ===================================================================
|
| --- resources/bookmark_manager/js/cr/ui/menubutton.js (revision 0)
|
| +++ resources/bookmark_manager/js/cr/ui/menubutton.js (revision 0)
|
| @@ -0,0 +1,166 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +cr.define('cr.ui', function() {
|
| + const Menu = cr.ui.Menu;
|
| +
|
| + /**
|
| + * Creates a new menu button element.
|
| + * @param {Object=} opt_propertyBag Optional properties.
|
| + * @constructor
|
| + * @extends {HTMLButtonElement}
|
| + */
|
| + var MenuButton = cr.ui.define('button');
|
| +
|
| + MenuButton.prototype = {
|
| + __proto__: HTMLButtonElement.prototype,
|
| +
|
| + /**
|
| + * Initializes the menu button.
|
| + */
|
| + decorate: function() {
|
| + this.addEventListener('mousedown', this);
|
| + this.addEventListener('keydown', this);
|
| +
|
| + var menu;
|
| + if ((menu = this.getAttribute('menu')))
|
| + this.menu = menu;
|
| + },
|
| +
|
| + /**
|
| + * The menu associated with the menu button.
|
| + * @type {cr.ui.Menu}
|
| + */
|
| + get menu() {
|
| + return this.menu_;
|
| + },
|
| + set menu(menu) {
|
| + if (typeof menu == 'string' && menu[0] == '#') {
|
| + menu = this.ownerDocument.getElementById(menu.slice(1));
|
| + cr.ui.decorate(menu, Menu);
|
| + }
|
| +
|
| + this.menu_ = menu;
|
| + if (menu) {
|
| + if (menu.id)
|
| + this.setAttribute('menu', '#' + menu.id);
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Handles event callbacks.
|
| + * @param {Event} e The event object.
|
| + */
|
| + handleEvent: function(e) {
|
| + if (!this.menu)
|
| + return;
|
| +
|
| + switch (e.type) {
|
| + case 'mousedown':
|
| + if (e.currentTarget == this.ownerDocument) {
|
| + if (!this.contains(e.target) && !this.menu.contains(e.target))
|
| + this.hideMenu();
|
| + else
|
| + e.preventDefault();
|
| + } else {
|
| + if (this.isMenuShown()) {
|
| + this.hideMenu();
|
| + } else {
|
| + this.showMenu();
|
| + // Prevent the button from stealing focus on mousedown.
|
| + e.preventDefault();
|
| + }
|
| + }
|
| + break;
|
| + case 'keydown':
|
| + this.handleKeyDown(e);
|
| + // If the menu is visible we let it handle all the keyboard events.
|
| + if (this.isMenuShown() && e.currentTarget == this.ownerDocument) {
|
| + this.menu.handleKeyDown(e);
|
| + e.preventDefault();
|
| + e.stopPropagation();
|
| + }
|
| + break;
|
| +
|
| + case 'activate':
|
| + case 'blur':
|
| + this.hideMenu();
|
| + break;
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Shows the menu.
|
| + */
|
| + showMenu: function() {
|
| + this.menu.style.display = 'block';
|
| + // when the menu is shown we steal all keyboard events.
|
| + this.ownerDocument.addEventListener('keydown', this, true);
|
| + this.ownerDocument.addEventListener('mousedown', this, true);
|
| + this.ownerDocument.addEventListener('blur', this, true);
|
| + this.menu.addEventListener('activate', this);
|
| + this.positionMenu_();
|
| + },
|
| +
|
| + /**
|
| + * Hides the menu.
|
| + */
|
| + hideMenu: function() {
|
| + this.menu.style.display = 'none';
|
| + this.ownerDocument.removeEventListener('keydown', this, true);
|
| + this.ownerDocument.removeEventListener('mousedown', this, true);
|
| + this.ownerDocument.removeEventListener('blur', this, true);
|
| + this.menu.removeEventListener('activate', this);
|
| + this.menu.selectedIndex = -1;
|
| + },
|
| +
|
| + /**
|
| + * Whether the menu is shown.
|
| + */
|
| + isMenuShown: function() {
|
| + return window.getComputedStyle(this.menu).display != 'none';
|
| + },
|
| +
|
| + /**
|
| + * Positions the menu below the menu button. At this point we do not use any
|
| + * advanced positioning logic to ensure the menu fits in the viewport.
|
| + * @private
|
| + */
|
| + positionMenu_: function() {
|
| + var buttonRect = this.getBoundingClientRect();
|
| + this.menu.style.top = buttonRect.bottom + 'px';
|
| + if (getComputedStyle(this).direction == 'rtl') {
|
| + var menuRect = this.menu.getBoundingClientRect();
|
| + this.menu.style.left = buttonRect.right - menuRect.width + 'px';
|
| + } else {
|
| + this.menu.style.left = buttonRect.left + 'px';
|
| + }
|
| + },
|
| +
|
| + /**
|
| + * Handles the keydown event for the menu button.
|
| + */
|
| + handleKeyDown: function(e) {
|
| + switch (e.keyIdentifier) {
|
| + case 'Down':
|
| + case 'Up':
|
| + case 'Enter':
|
| + case 'U+0020': // Space
|
| + if (!this.isMenuShown())
|
| + this.showMenu();
|
| + e.preventDefault();
|
| + break;
|
| + case 'Esc':
|
| + case 'U+001B': // Maybe this is remote desktop playing a prank?
|
| + this.hideMenu();
|
| + break;
|
| + }
|
| + }
|
| + };
|
| +
|
| + // Export
|
| + return {
|
| + MenuButton: MenuButton
|
| + };
|
| +});
|
|
|