UNPKG

yy-menu

Version:

A traditional menu system for web apps inspired by Electron

436 lines (369 loc) 13.7 kB
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>yy-menu API Documentation</title> <meta name="description" content="Documentation for yy-menu library" /> <meta name="keywords" content="menu,system,UI,accelerators,Electron,file menu,web app" /> <meta name="keyword" content="menu,system,UI,accelerators,Electron,file menu,web app" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="scripts/prettify/prettify.js"></script> <script src="scripts/prettify/lang-css.js"></script> <script src="scripts/jquery.min.js"></script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet"> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css"> <link type="text/css" rel="stylesheet" href="styles/main.css"> <script> var config = {"monospaceLinks":false,"cleverLinks":false,"default":{"outputSourceFiles":true},"applicationName":"yy-menu","footer":"by YOPEY YOPEY LLC (yopeyopey.com)","copyright":"Copyright © 2018 YOPEY YOPEY LLC.","meta":{"title":"yy-menu API Documentation","description":"Documentation for yy-menu library","keyword":["menu","system","UI","accelerators","Electron","file menu","web app"]},"matomo":{"url":"https://analytics.yopeyopey.com/piwik/","id":18}}; </script> <script type="text/javascript"> var _paq = _paq || []; _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://analytics.yopeyopey.com/piwik/"; _paq.push(['setTrackerUrl', u+'piwik.php']); _paq.push(['setSiteId', '18']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s); })(); </script> </head> <body> <div id="wrap" class="clearfix"> <div class="navigation"> <h3 class="applicationName"><a href="index.html">yy-menu</a></h3> <button id="menuToggle" class="btn btn-link btn-lg menu-toggle"> <span class="glyphicon glyphicon-menu-hamburger"></span> </button> <div class="search"> <input id="search" type="text" class="form-control input-md" placeholder="Search..."> </div> <ul class="list"> <li class="item" data-name="global"> <span class="title namespace "> <span class="namespaceTag"> <span class="glyphicon glyphicon-globe"></span> </span> <a href="global.html">Global</a> </span> <ul class="members itemMembers"> <span class="subtitle">Members</span> <li class="parent " data-name="localAccelerator"><a href="global.html#localAccelerator">localAccelerator</a></li> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> </ul> <ul class="events itemMembers"> </ul> </li> <li class="item" data-name="Menu#Menu"> <span class="title "> <a href="Menu_Menu.html">Menu#Menu</a> </span> <ul class="members itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> </ul> <ul class="events itemMembers"> </ul> </li> <li class="item" data-name="MenuItem#MenuItem"> <span class="title "> <a href="MenuItem_MenuItem.html">MenuItem#MenuItem</a> </span> <ul class="members itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="typedefs itemMembers"> </ul> <ul class="methods itemMembers"> </ul> <ul class="events itemMembers"> </ul> </li> </ul> </div> <div class="main"> <h1 class="page-title" data-filename="Viewport">Source: localAccelerator.js</h1> <section> <header> <div class="header content-size"> <h2>localAccelerator.js</h2> </div> </header> <article> <pre id="source-code" class="prettyprint source "><code>/** * Handles all keyboard input for the menu and user-registered keys */ export const localAccelerator = { init: function () { if (!localAccelerator.menuKeys) { localAccelerator.menuKeys = {} localAccelerator.keys = {} document.body.addEventListener('keydown', (e) => localAccelerator.keydown(localAccelerator, e)) document.body.addEventListener('keyup', (e) => localAccelerator.keyup(localAccelerator, e)) } }, /** * clear all user-registered keys */ clearKeys: function () { localAccelerator.keys = {} }, /** * Register a shortcut key for use by an open menu * @param {KeyCodes} letter * @param {MenuItem} menuItem * @param {boolean} applicationMenu * @private */ registerMenuShortcut: function (letter, menuItem) { if (letter) { const keyCode = (menuItem.menu.applicationMenu ? 'alt+' : '') + letter localAccelerator.menuKeys[localAccelerator.prepareKey(keyCode)] = (e) => { menuItem.handleClick(e) e.stopPropagation() e.preventDefault() } } }, /** * Register special shortcut keys for menu * @param {MenuItem} menuItem * @private */ registerMenuSpecial: function (menu) { localAccelerator.menuKeys['escape'] = () => menu.closeAll() localAccelerator.menuKeys['enter'] = (e) => menu.enter(e) localAccelerator.menuKeys['space'] = (e) => menu.enter(e) localAccelerator.menuKeys['arrowright'] = (e) => menu.move(e, 'right') localAccelerator.menuKeys['arrowleft'] = (e) => menu.move(e, 'left') localAccelerator.menuKeys['arrowup'] = (e) => menu.move(e, 'up') localAccelerator.menuKeys['arrowdown'] = (e) => menu.move(e, 'down') }, /** * special key registration for alt * @param {function} pressed * @param {function} released * @private */ registerAlt: function (pressed, released) { localAccelerator.alt = { pressed, released } }, /** * Removes menu shortcuts * @private */ unregisterMenuShortcuts: function () { localAccelerator.menuKeys = {} }, /** * Keycodes definition. In the form of modifier[+modifier...]+key * &lt;p>For example: ctrl+shift+e&lt;/p> * &lt;p>KeyCodes are case insensitive (i.e., shift+a is the same as Shift+A). And spaces are removed&lt;/p> * &lt;p>You can assign more than one key to the same shortcut by using a | between the keys (e.g., 'shift+a | ctrl+a')&lt;/p> * &lt;pre> * Modifiers: * ctrl, alt, shift, meta, (ctrl aliases: command, control, commandorcontrol) * &lt;/pre> * &lt;pre> * Keys: * escape, 0-9, minus, equal, backspace, tab, a-z, backetleft, bracketright, semicolon, quote, * backquote, backslash, comma, period, slash, numpadmultiply, space, capslock, f1-f24, pause, * scrolllock, printscreen, home, arrowup, arrowleft, arrowright, arrowdown, pageup, pagedown, * end, insert, delete, enter, shiftleft, shiftright, ctrlleft, ctrlright, altleft, altright, shiftleft, * shiftright, numlock, numpad... * &lt;/pre> * For OS-specific codes and a more detailed explanation see {@link https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code}. Also note that 'Digit' and 'Key' are removed from the code to make it easier to type. * * @typedef {string} localAccelerator~KeyCodes */ /** * translate a user-provided keycode * @param {KeyCodes} keyCode * @return {KeyCodes} formatted and sorted keyCode * @private */ prepareKey: function (keyCode) { const keys = [] let split keyCode += '' if (keyCode.length > 1 &amp;&amp; keyCode.indexOf('|') !== -1) { split = keyCode.split('|') } else { split = [keyCode] } for (let code of split) { let key = '' let modifiers = [] code = code.toLowerCase().replace(' ', '') if (code.indexOf('+') !== -1) { const split = code.split('+') for (let i = 0; i &lt; split.length - 1; i++) { let modifier = split[i] modifier = modifier.replace('commandorcontrol', 'ctrl') modifier = modifier.replace('command', 'ctrl') modifier = modifier.replace('control', 'ctrl') modifiers.push(modifier) } modifiers = modifiers.sort((a, b) => { return a[0] > b[0] ? 1 : a[0] &lt; b[0] ? -1 : 0 }) for (let part of modifiers) { key += part + '+' } key += split[split.length - 1] } else { key = code } keys.push(key) } return keys }, /** * Make the KeyCode pretty for printing on the menu * @param {KeyCode} keyCode * @return {string} * @private */ prettifyKey: function (keyCode) { let key = '' const codes = localAccelerator.prepareKey(keyCode) for (let i = 0; i &lt; codes.length; i++) { const keyCode = codes[i] if (keyCode.indexOf('+') !== -1) { const split = keyCode.toLowerCase().split('+') for (let i = 0; i &lt; split.length - 1; i++) { let modifier = split[i] key += modifier[0].toUpperCase() + modifier.substr(1) + '+' } key += split[split.length - 1].toUpperCase() } else { key = keyCode.toUpperCase() } if (i !== codes.length - 1) { key += ' or ' } } return key }, /** * register a key as a global accelerator * @param {KeyCodes} keyCode (e.g., Ctrl+shift+E) * @param {function} callback */ register: function (keyCode, callback) { const keys = localAccelerator.prepareKey(keyCode) for (let key of keys) { localAccelerator.keys[key] = (e) => { callback(e) e.preventDefault() e.stopPropagation() } } }, keyup: function (accelerator, e) { if (localAccelerator.alt &amp;&amp; (e.code === 'AltLeft' || e.code === 'AltRight')) { localAccelerator.alt.released() localAccelerator.alt.isPressed = false } }, keydown: function (accelerator, e) { if (localAccelerator.alt &amp;&amp; !localAccelerator.alt.isPressed &amp;&amp; (e.code === 'AltLeft' || e.code === 'AltRight')) { localAccelerator.alt.pressed() localAccelerator.alt.isPressed = true e.preventDefault() } const modifiers = [] if (e.altKey) { modifiers.push('alt') } if (e.ctrlKey) { modifiers.push('ctrl') } if (e.metaKey) { modifiers.push('meta') } if (e.shiftKey) { modifiers.push('shift') } let keyCode = '' for (let modifier of modifiers) { keyCode += modifier + '+' } let translate = e.code.toLowerCase() translate = translate.replace('digit', '') translate = translate.replace('key', '') keyCode += translate if (localAccelerator.menuKeys[keyCode]) { localAccelerator.menuKeys[keyCode](e, localAccelerator) } else if (localAccelerator.keys[keyCode]) { localAccelerator.keys[keyCode](e, localAccelerator) } } }</code></pre> </article> </section> <footer class="content-size"> <div class="footer"> Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.6</a> on Wed Dec 23 2020 11:20:22 GMT+0800 (Taipei Standard Time) </div> </footer> </div> </div> <script>prettyPrint();</script> <script src="scripts/main.js"></script> </body> </html>