class ContextMenu { static Type = { PropertyItem: 'property-item', ClassListItem: 'class-list-item' }; static init() { if(!DOM.get('.context-menu')) return null; if(this.instance) return this.instance; return this.instance = new ContextMenu(); } constructor() { this.dom = DOM.get('.context-menu'); this.items = {}; } show(pos) { this.dom.style('left', `${pos.x}px`).style('top', `${pos.y}px`); this.dom.removeClass('hidden'); } addDelimiter() { DOM.create({ tag: DOM.Tags.Div, cls: 'context-menu-delimiter' }, this.dom); return this; } addItem(name, text, action) { const itemAction = (e) => { action(e); this.hide(); }; this.items[name] = new ContextMenuItem(name, text, itemAction, this.dom).render(); return this; } clear() { for(const child of this.dom.getChildren()) { const name = child.getAttribute('data-context-menu-item-name'); if(name) { this.items[name].dispose(); this.items[name] = null; delete this.items[name]; } child.remove(); } return this; } hide() { if(this.dom.hasClass('hidden')) return this; this.dom.addClass('hidden'); this.clear(); return this; } } window_.on(DOM.Events.MouseDown, (e) => { const contextMenu = ContextMenu.init(); if(!contextMenu) return; let target = CDElement.get(e.target); while(target != null && !target.hasClass('context-menu')) { target = target.getParent(); } if(target != null && target.hasClass('context-menu')) return; contextMenu.hide(); });