yy-menu
Version:
A traditional menu system for web apps inspired by Electron
415 lines (345 loc) • 12.7 kB
HTML
<!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: MenuItem.js</h1>
<section>
<header>
<div class="header content-size">
<h2>MenuItem.js</h2>
</div>
</header>
<article>
<pre id="source-code" class="prettyprint source "><code>import { html } from './html'
import { config } from './config'
import { localAccelerator } from './localAccelerator'
export class MenuItem
{
/**
* @param {object} options
* @param {string} [options.label] label for menu entry may include accelerator by placing & before letter)
* @param {string} [options.type] separator, checkbox, or undefined
* @param {object} [options.styles] additional CSS styles to apply to this MenuItem
* @param {string} [options.accelerator] see Accelerator for inputs (e.g., ctrl+shift+A)
* @param {MenuItem} [options.submenu] attaches a submenu (and changes type to submenu)
* @param {boolean} [options.checked] check the checkbox
*/
constructor(options)
{
localAccelerator.init()
options = options || {}
this.styles = options.styles
this.div = html()
this.type = options.type
this.click = options.click
if (this.type === 'separator')
{
this.applyConfig(config.SeparatorStyle)
}
else
{
this._checked = options.checked
this.createChecked(options.checked)
this.text = options.label || '&nbsp;&nbsp;&nbsp;'
this.createShortcut()
this.createAccelerator(options.accelerator)
this.createSubmenu(options.submenu)
if (options.submenu)
{
this.submenu = options.submenu
this.submenu.applyConfig(config.MenuStyle)
}
this.applyConfig(config.RowStyle)
this.div.addEventListener('mousedown', (e) => this.handleClick(e))
this.div.addEventListener('touchstart', (e) => this.handleClick(e))
this.div.addEventListener('mouseenter', () => this.mouseenter())
this.div.addEventListener('mouseleave', () => this.mouseleave())
}
}
/**
* The click callback
* @callback MenuItem~ClickCallback
* @param {InputEvent} e
*/
mouseenter()
{
if (!this.submenu || this.menu.showing !== this )
{
this.div.style.backgroundColor = config.SelectedBackgroundStyle
if (this.submenu && (!this.menu.applicationMenu || this.menu.showing))
{
this.submenuTimeout = setTimeout(() =>
{
this.submenuTimeout = null
this.submenu.show(this)
}, this.menu.applicationMenu ? 0 : config.SubmenuOpenDelay)
}
}
}
mouseleave()
{
if (!this.submenu || this.menu.showing !== this)
{
if (this.submenuTimeout)
{
clearTimeout(this.submenuTimeout)
this.submenuTimeout = null
}
this.div.style.backgroundColor = 'transparent'
}
}
applyConfig(base)
{
const styles = {}
for (let style in base)
{
styles[style] = base[style]
}
if (this.styles)
{
for (let style in this.styles)
{
styles[style] = this.styles[style]
}
}
for (let style in styles)
{
this.div.style[style] = styles[style]
}
}
createChecked(checked)
{
this.check = html({ parent: this.div, html: checked ? '&#10004;' : '' })
}
createShortcut()
{
if (this.type !== 'separator')
{
const text = this.text
this.label = html({ parent: this.div })
let current = html({ parent: this.label, type: 'span' })
if (text.indexOf('&') !== -1)
{
let i = 0
do
{
const letter = text[i]
if (letter === '&')
{
i++
this.shortcutSpan = html({ parent: this.label, type: 'span', html: text[i], styles: config.AcceleratorKeyStyle })
current = html({ parent: this.label, type: 'span' })
}
else
{
current.innerHTML += letter
}
i++
}
while (i < text.length)
}
else
{
this.label.innerHTML = text
}
}
}
showShortcut()
{
if (this.shortcutSpan)
{
this.shortcutSpan.style.textDecoration = 'underline'
}
}
hideShortcut()
{
if (this.shortcutSpan)
{
this.shortcutSpan.style.textDecoration = 'none'
}
}
createAccelerator(accelerator)
{
this.accelerator = html({ parent: this.div, html: accelerator ? localAccelerator.prettifyKey(accelerator) : '', styles: config.AcceleratorStyle })
if (accelerator)
{
localAccelerator.register(accelerator, (e) => this.click(e))
}
}
createSubmenu(submenu)
{
this.arrow = html({ parent: this.div, html: submenu ? '&#9658;' : '' })
}
closeAll()
{
let menu = this.menu
localAccelerator.unregisterMenuShortcuts()
while (menu && !menu.applicationMenu)
{
if (menu.showing)
{
menu.showing.div.style.backgroundColor = 'transparent'
menu.showing = null
}
menu.div.remove()
menu = menu.menu
}
if (menu.showing)
{
menu.showing.div.style.background = 'transparent'
menu.showing = null
menu.hideAccelerators()
}
}
handleClick(e)
{
if (this.submenu)
{
if (this.submenuTimeout)
{
clearTimeout(this.submenuTimeout)
this.submenuTimeout = null
}
this.submenu.show(this)
this.div.style.backgroundColor = config.SelectedBackgroundStyle
if (typeof e !== 'undefined' && this.menu.applicationMenu && document.activeElement !== this.menu.div)
{
this.menu.div.focus()
}
if (e)
{
e.preventDefault()
}
}
else if (this.type === 'checkbox')
{
this.checked = !this.checked
this.closeAll()
}
else
{
this.closeAll()
}
if (this.click)
{
this.click(e, this)
}
}
get checked()
{
return this._checked
}
set checked(value)
{
this._checked = value
this.check.innerHTML = this._checked ? '&#10004;' : ''
}
}</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>