From bc0416e7eef3b15881b81058efa876407701b79f Mon Sep 17 00:00:00 2001 From: Jon Gunderson Date: Fri, 13 Oct 2017 13:36:32 -0500 Subject: [PATCH] Menu Button Examples: Remove space activation key for menuitems (pull #478) For issue #403, this removes space as a way to activate a menu item. We chose to remove because @jongund believes there is a bug in Firefox that was triggering a click on the button after the menuitem was activated. Space did not exhibit this behavior in other browsers. --- examples/menu-button/js/MenuItemAction.js | 82 ++++++++----------- examples/menu-button/js/MenuItemLinks.js | 4 + examples/menu-button/js/PopupMenuAction.js | 3 +- .../js/PopupMenuActionActivedescendant.js | 4 + examples/menu-button/menu-button-actions.html | 22 ++--- 5 files changed, 56 insertions(+), 59 deletions(-) diff --git a/examples/menu-button/js/MenuItemAction.js b/examples/menu-button/js/MenuItemAction.js index c565a11428..58a82614d9 100644 --- a/examples/menu-button/js/MenuItemAction.js +++ b/examples/menu-button/js/MenuItemAction.js @@ -24,10 +24,10 @@ * The object that is a wrapper for the PopupMenu DOM element that * contains the menu item DOM element. See PopupMenuAction.js */ -var MenuItem = function (domNode, menuObj) { +var PopupMenuItem = function (domNode, popupMenuObj) { - this.domNode = domNode; - this.menu = menuObj; + this.domNode = domNode; + this.popupMenu = popupMenuObj; this.keyCode = Object.freeze({ 'TAB': 9, @@ -45,7 +45,7 @@ var MenuItem = function (domNode, menuObj) { }); }; -MenuItem.prototype.init = function () { +PopupMenuItem.prototype.init = function () { this.domNode.tabIndex = -1; if (!this.domNode.getAttribute('role')) { @@ -63,7 +63,7 @@ MenuItem.prototype.init = function () { /* EVENT HANDLERS */ -MenuItem.prototype.handleKeydown = function (event) { +PopupMenuItem.prototype.handleKeydown = function (event) { var tgt = event.currentTarget, flag = false, char = event.key, @@ -79,70 +79,57 @@ MenuItem.prototype.handleKeydown = function (event) { if (event.shiftKey) { if (isPrintableCharacter(char)) { - this.menu.setFocusByFirstCharacter(this, char); + this.popupMenu.setFocusByFirstCharacter(this, char); } } else { switch (event.keyCode) { case this.keyCode.SPACE: + flag = true; + break; + case this.keyCode.RETURN: - // Create simulated mouse event to mimic the behavior of ATs - // and let the event handler handleClick do the housekeeping. - try { - clickEvent = new MouseEvent('click', { - 'view': window, - 'bubbles': true, - 'cancelable': true - }); - } - catch (err) { - if (document.createEvent) { - // DOM Level 3 for IE 9+ - clickEvent = document.createEvent('MouseEvents'); - clickEvent.initEvent('click', true, true); - } - } - tgt.dispatchEvent(clickEvent); + this.handleClick(event); flag = true; break; case this.keyCode.ESC: - this.menu.setFocusToController(); - this.menu.close(true); + this.popupMenu.setFocusToController(); + this.popupMenu.close(true); flag = true; break; case this.keyCode.UP: - this.menu.setFocusToPreviousItem(this); + this.popupMenu.setFocusToPreviousItem(this); flag = true; break; case this.keyCode.DOWN: - this.menu.setFocusToNextItem(this); + this.popupMenu.setFocusToNextItem(this); flag = true; break; case this.keyCode.HOME: case this.keyCode.PAGEUP: - this.menu.setFocusToFirstItem(); + this.popupMenu.setFocusToFirstItem(); flag = true; break; case this.keyCode.END: case this.keyCode.PAGEDOWN: - this.menu.setFocusToLastItem(); + this.popupMenu.setFocusToLastItem(); flag = true; break; case this.keyCode.TAB: - this.menu.setFocusToController(); - this.menu.close(true); + this.popupMenu.setFocusToController(); + this.popupMenu.close(true); break; default: if (isPrintableCharacter(char)) { - this.menu.setFocusByFirstCharacter(this, char); + this.popupMenu.setFocusByFirstCharacter(this, char); } break; } @@ -154,27 +141,30 @@ MenuItem.prototype.handleKeydown = function (event) { } }; -MenuItem.prototype.handleClick = function (event) { - this.menu.setFocusToController(); - this.menu.close(true); +PopupMenuItem.prototype.handleClick = function (event) { + if (menuAction) { + menuAction(event); + } + this.popupMenu.setFocusToController(); + this.popupMenu.close(true); }; -MenuItem.prototype.handleFocus = function (event) { - this.menu.hasFocus = true; +PopupMenuItem.prototype.handleFocus = function (event) { + this.popupMenu.hasFocus = true; }; -MenuItem.prototype.handleBlur = function (event) { - this.menu.hasFocus = false; - setTimeout(this.menu.close.bind(this.menu, false), 300); +PopupMenuItem.prototype.handleBlur = function (event) { + this.popupMenu.hasFocus = false; + setTimeout(this.popupMenu.close.bind(this.popupMenu, false), 300); }; -MenuItem.prototype.handleMouseover = function (event) { - this.menu.hasHover = true; - this.menu.open(); +PopupMenuItem.prototype.handleMouseover = function (event) { + this.popupMenu.hasHover = true; + this.popupMenu.open(); }; -MenuItem.prototype.handleMouseout = function (event) { - this.menu.hasHover = false; - setTimeout(this.menu.close.bind(this.menu, false), 300); +PopupMenuItem.prototype.handleMouseout = function (event) { + this.popupMenu.hasHover = false; + setTimeout(this.popupMenu.close.bind(this.popupMenu, false), 300); }; diff --git a/examples/menu-button/js/MenuItemLinks.js b/examples/menu-button/js/MenuItemLinks.js index 067766d36e..13e1a2fac3 100644 --- a/examples/menu-button/js/MenuItemLinks.js +++ b/examples/menu-button/js/MenuItemLinks.js @@ -85,6 +85,10 @@ MenuItemLinks.prototype.handleKeydown = function (event) { else { switch (event.keyCode) { + case this.keyCode.SPACE: + flag = true; + break; + case this.keyCode.ESC: this.menu.setFocusToController(); this.menu.close(true); diff --git a/examples/menu-button/js/PopupMenuAction.js b/examples/menu-button/js/PopupMenuAction.js index 8840056808..883b0c12e1 100644 --- a/examples/menu-button/js/PopupMenuAction.js +++ b/examples/menu-button/js/PopupMenuAction.js @@ -102,7 +102,7 @@ PopupMenuAction.prototype.init = function () { menuElement = menuElements[i]; if (!menuElement.firstElementChild && menuElement.getAttribute('role') != 'separator') { - menuItem = new MenuItem(menuElement, this); + menuItem = new PopupMenuItem(menuElement, this); menuItem.init(); this.menuitems.push(menuItem); textContent = menuElement.textContent.trim(); @@ -230,7 +230,6 @@ PopupMenuAction.prototype.open = function () { }; PopupMenuAction.prototype.close = function (force) { - if (typeof force !== 'boolean') { force = false; } diff --git a/examples/menu-button/js/PopupMenuActionActivedescendant.js b/examples/menu-button/js/PopupMenuActionActivedescendant.js index 05ee59e6a0..a103fc91d3 100644 --- a/examples/menu-button/js/PopupMenuActionActivedescendant.js +++ b/examples/menu-button/js/PopupMenuActionActivedescendant.js @@ -157,7 +157,11 @@ PopupMenuActionActivedescendant.prototype.handleKeydown = function (event) { } else { switch (event.keyCode) { + case this.keyCode.SPACE: + flag = true; + break; + case this.keyCode.RETURN: // Create simulated mouse event to mimic the behavior of ATs // and let the event handler handleClick do the housekeeping. diff --git a/examples/menu-button/menu-button-actions.html b/examples/menu-button/menu-button-actions.html index cb748ea374..6d377d7c70 100644 --- a/examples/menu-button/menu-button-actions.html +++ b/examples/menu-button/menu-button-actions.html @@ -20,14 +20,14 @@

Actions Menu Button Example Using element.focus()

- This example demonstrates how the + This example demonstrates how the menu button design pattern can be used to create a button that opens an actions menu. In this example, choosing an action from the menu will cause the chosen action to be displayed in the Last Action edit box.

In this implementation, each item in the menu is made focusable by setting tabindex="-1" so the JavaScript can use element.focus() to set focus in response to events that trigger focus movement inside the menu. - An alternative technique for managing focus movement among menu items is demonstrated in + An alternative technique for managing focus movement among menu items is demonstrated in the action menu button example that uses aria-activedescendant.

Similar examples include:

@@ -49,10 +49,10 @@

Example

@@ -62,7 +62,7 @@

Example

- +