61 lines
1.8 KiB
JavaScript
61 lines
1.8 KiB
JavaScript
import { SVG, DOM } from './DOM.js'
|
|
/**
|
|
* Context menus globally managed
|
|
* <node>s that have a contextmenu handler at capture time put their menu
|
|
* under event.menu property and this final bubble handler on document
|
|
* creates the menu HTML in a SVG's <foreignObject>.
|
|
*/
|
|
document.xxxoncontextmenu = e=> {
|
|
console.log(e)
|
|
// console.log(e.path)
|
|
console.log(e.menu)
|
|
// let items = e.menu//path.reverse().reduce( (m,n)=> ({...m,...(n.menu?n.menu:{})}),{})
|
|
// console.log(items, Object.keys(items).length )
|
|
if( e.menu )
|
|
{
|
|
e.preventDefault()
|
|
// let menu
|
|
// , layer = UI.Overlay( menu = UI.Menu( items ) )
|
|
// menu.setAttribute( 'x', e.clientX )
|
|
// menu.setAttribute( 'y', e.clientY )
|
|
// menu.style.transform = `translate( ${e.clientX}px, ${e.clientY}px )`
|
|
// menu.style.position = 'absolute'
|
|
// document.documentElement.append( layer )
|
|
document.documentElement.append(
|
|
Overlay(
|
|
ContextMenu( e, e.menu )
|
|
)
|
|
)
|
|
}
|
|
}
|
|
const Overlay = ( ...items )=> {
|
|
let html = SVG`<foreignObject width="100%" height="100%"/>`[0]
|
|
html.append( ...items )
|
|
html.one`click`( e=> /*e.target == html && */html.remove() )
|
|
return html
|
|
}
|
|
const Menu = ( items, label )=> {
|
|
let html = DOM`<menu xmlns="http://www.w3.org/1999/xhtml"${label ? ` label="${label}"` : ''}></menu>`.children[0]
|
|
, btn
|
|
html.append(
|
|
...Object.keys( items )
|
|
.map( k=> typeof items[k] == 'object'
|
|
? Menu( items[k], k )
|
|
: ( btn = DOM`<button>${k}</button>`.children[0], btn.on`click`( items[k] ), btn )
|
|
)
|
|
// ...items.map( item=> DOM`<button>${item.label}</button>`)
|
|
)
|
|
return html
|
|
}
|
|
const ContextMenu = ( {x,y}, items )=> {
|
|
let menu = Menu( items )
|
|
menu.style.transform = `translate( ${x}px, ${y}px )`
|
|
menu.style.position = 'absolute'
|
|
return menu
|
|
}
|
|
|
|
export {
|
|
Overlay
|
|
, Menu
|
|
, ContextMenu
|
|
} |