1export function MenubarItemAction(aria) { 2 /* 3 * This content is licensed according to the W3C Software License at 4 * https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document 5 * 6 * File: MenubarItemAction.js 7 * 8 * Desc: Menubar Menuitem widget that implements ARIA Authoring Practices 9 */ 10 11 /* 12 * @constructor MenubarItemAction 13 * 14 * @desc 15 * Object that configures menubar item elements by setting tabIndex 16 * and registering itself to handle pertinent events. 17 * 18 * @param domNode 19 * The DOM element node that serves as the menubar item container. 20 * The menubarObj is responsible for checking that it has 21 * requisite metadata, e.g. role="menuitem". 22 * 23 * @param menubarObj 24 * The MenubarAction object that is a delegate for the menubar DOM element 25 * that contains the menubar item element. 26 */ 27 aria.MenubarItemAction = function (domNode, menubarObj) { 28 29 this.menubar = menubarObj; 30 this.domNode = domNode; 31 this.popupMenu = false; 32 33 this.keyCode = Object.freeze({ 34 'TAB': 9, 35 'RETURN': 13, 36 'ESC': 27, 37 'SPACE': 32, 38 'PAGEUP': 33, 39 'PAGEDOWN': 34, 40 'END': 35, 41 'HOME': 36, 42 'LEFT': 37, 43 'UP': 38, 44 'RIGHT': 39, 45 'DOWN': 40 46 }); 47 }; 48 49 aria.MenubarItemAction.prototype.init = function () { 50 this.domNode.tabIndex = -1; 51 52 this.domNode.addEventListener('keydown', this.handleKeydown.bind(this)); 53 this.domNode.addEventListener('click', this.handleClick.bind(this)); 54 this.domNode.addEventListener('mouseover', this.handleMouseover.bind(this)); 55 56 // initialize pop up menus 57 58 var nextElement = this.domNode.nextElementSibling; 59 60 if (nextElement && nextElement.tagName === 'UL') { 61 this.popupMenu = new aria.PopupMenuAction(nextElement, this, this.menubar.actionManager); 62 this.popupMenu.init(); 63 } 64 65 }; 66 67 aria.MenubarItemAction.prototype.handleKeydown = function (event) { 68 var tgt = event.currentTarget, 69 char = event.key, 70 flag = false; 71 72 function isPrintableCharacter (str) { 73 return str.length === 1 && str.match(/\S/); 74 } 75 76 switch (event.keyCode) { 77 case this.keyCode.SPACE: 78 case this.keyCode.RETURN: 79 case this.keyCode.DOWN: 80 if (this.popupMenu) { 81 this.popupMenu.open(); 82 this.popupMenu.setFocusToFirstItem(); 83 flag = true; 84 } 85 break; 86 87 case this.keyCode.ESC: 88 if (this.popupMenu) { 89 this.popupMenu.close(); 90 } 91 flag = true; 92 break; 93 94 case this.keyCode.LEFT: 95 this.menubar.setFocusToPreviousItem(this); 96 flag = true; 97 break; 98 99 case this.keyCode.RIGHT: 100 this.menubar.setFocusToNextItem(this); 101 flag = true; 102 break; 103 104 case this.keyCode.UP: 105 if (this.popupMenu) { 106 this.popupMenu.open(); 107 this.popupMenu.setFocusToLastItem(); 108 flag = true; 109 } 110 break; 111 112 case this.keyCode.HOME: 113 case this.keyCode.PAGEUP: 114 this.menubar.setFocusToFirstItem(); 115 if (this.popupMenu) { 116 this.popupMenu.close(); 117 } 118 flag = true; 119 break; 120 121 case this.keyCode.END: 122 case this.keyCode.PAGEDOWN: 123 this.menubar.setFocusToLastItem(); 124 if (this.popupMenu) { 125 this.popupMenu.close(); 126 } 127 flag = true; 128 break; 129 130 case this.keyCode.ESC: 131 if (this.popupMenu) { 132 this.popupMenu.close(); 133 } 134 flag = true; 135 break; 136 137 default: 138 if (isPrintableCharacter(char)) { 139 this.menubar.setFocusByFirstCharacter(this, char); 140 flag = true; 141 } 142 break; 143 } 144 145 if (flag) { 146 event.stopPropagation(); 147 event.preventDefault(); 148 } 149 }; 150 151 aria.MenubarItemAction.prototype.handleClick = function (event) { 152 if (this.popupMenu) { 153 if (!this.popupMenu.isOpen()) { 154 // clicking on menubar item opens menu (closes open menu first) 155 for (var i = 0; i < this.menubar.menubarItems.length; i++) { 156 var mbi = this.menubar.menubarItems[i]; 157 if (mbi.popupMenu && mbi.popupMenu.isOpen()) { 158 mbi.popupMenu.close(); 159 break; 160 } 161 } 162 this.popupMenu.open(); 163 } 164 else { 165 // clicking again on same menubar item closes menu 166 this.popupMenu.close(); 167 } 168 // prevent scroll to top of page when anchor element is clicked 169 event.preventDefault(); 170 } 171 }; 172 173 aria.MenubarItemAction.prototype.handleMouseover = function (event) {
174 this.menubar.setFocusToItem(this, true); 175 }; 176}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.