goog.loadJs('common', () => { goog.require('path'); goog.require('tippy'); goog.require('Mixly.Env'); goog.require('Mixly.Menu'); goog.require('Mixly.Registry'); goog.require('Mixly.HTMLTemplate'); goog.require('Mixly.IdGenerator'); goog.require('Mixly.ContextMenu'); goog.require('Mixly.DropdownMenu'); goog.provide('Mixly.DropdownMenuGroup'); const { Env, Menu, Registry, HTMLTemplate, IdGenerator, ContextMenu, DropdownMenu } = Mixly; class DropdownMenuGroup { static { HTMLTemplate.add( 'html/dropdown-menu-item.html', new HTMLTemplate(goog.readFileSync(path.join(Env.templatePath, 'html/dropdown-menu-item.html'))) ); } #singleton_ = null; #menuItems_ = []; #ids_ = {}; #instanceIds_ = {}; #activeInstance_ = null; #instanceShown_ = false; #menuShown_ = false; #trigged_ = false; #$instancePopper_ = null; #$instanceContent_ = null; #$content_ = null; constructor(elem) { this.#$content_ = $(elem); this.#$content_.css('z-index', 200); this.#singleton_ = tippy.createSingleton([], { interactive: true, maxWidth: 'none', offset: [0, 3], appendTo: document.body, arrow: false, placement: 'bottom-end', animation: 'shift-toward-extreme', hideOnClick: false, delay: [200, null], onShow: () => { if (this.#activeInstance_) { this.showMenu(this.#activeInstance_.id); } this.#instanceShown_ = true; }, onTrigger: (_, event) => { const id = $(event.currentTarget).attr('data-id'); if (this.#instanceShown_) { if (this.#activeInstance_) { this.#trigged_ = true; this.hideMenu(this.#activeInstance_.id); this.#activeInstance_ = null; } this.showMenu(id); } this.#activeInstance_ = this.#instanceIds_[id].instance; }, onHide: () => { if (this.#menuShown_) { return false; } this.#instanceShown_ = false; return true; } }); this.#$instancePopper_ = $(this.#singleton_.popper); this.#$instancePopper_.addClass('mixly-drapdown-menu'); this.#$instanceContent_ = this.#$instancePopper_.children().children(); } add(item) { if (!item.id) { if (item.type) { item.id = item.type; } else { item.id = IdGenerator.generate(); } } if (!item.weight) { item.weight = 0; } this.remove(item.id); item.$elem = $(HTMLTemplate.get('html/dropdown-menu-item.html').render({ text: item.displayText })); const instance = tippy(item.$elem[0]); item.$elem.attr('data-id', instance.id); item.$i = item.$elem.children('i'); item.instance = instance; const contextMenuId = IdGenerator.generate(); const selector = `body > .mixly-dropdown-menus > div[m-id="${contextMenuId}"]`; const contextMenu = new ContextMenu(selector, { trigger: 'none', appendTo: this.#$instanceContent_, shadow: true, autoHide: false, async: false, zIndex: 150, position: (opt) => { opt.$menu.css('margin', 0); }, events: { show: (opt) => { item.$i.addClass('menu-shown'); this.#menuShown_ = true; this.#singleton_.setProps({}); }, hide: (opt) => { item.$i.removeClass('menu-shown'); if (this.#trigged_) { this.#trigged_ = false; return true; } this.#menuShown_ = false; this.#singleton_.hide(); } } }); item.contextMenu = contextMenu; contextMenu.register('menu', item.menu); contextMenu.bind('getMenu', () => 'menu'); item.$menu = $(`
`); DropdownMenu.$container.append(item.$menu); let i = 0; for (; i < this.#menuItems_.length; i++) { if (this.#menuItems_[i].weight <= item.weight) { continue; } break; } if (i === this.#menuItems_.length) { if (this.#menuItems_.length) { this.#menuItems_[i - 1].$elem.after(item.$elem); } else { this.#$content_.append(item.$elem); } } else { this.#menuItems_[i].$elem.before(item.$elem); } this.#menuItems_.splice(i, 0, item); this.#ids_[item.id] = item; this.#instanceIds_[instance.id] = item; const instances = []; for (let menuItem of this.#menuItems_) { instances.push(menuItem.instance); } this.#singleton_.setInstances(instances); return item.id; } getContextMenu(id) { if (!this.#ids_[id]) { return null; } return this.#ids_[id].contextMenu; } getInstance() { return this.#singleton_; } remove(id) { let item = this.#ids_[id]; if (!item) { return; } delete this.#ids_[id]; const instanceId = item.instance.id; delete this.#instanceIds_[instanceId]; for (let i in this.#menuItems_) { if (this.#menuItems_[i].id !== id) { continue; } this.#menuItems_.splice(i, 1); break; } item.instance.destroy(); item.contextMenu.dispose(); item.$elem.remove(); item.$menu.remove(); item = null; } showMenu(instanceId) { const item = this.#instanceIds_[instanceId]; item.$menu.contextMenu(); } hideMenu(instanceId) { const item = this.#instanceIds_[instanceId]; item.$menu.contextMenu('hide'); } dispose() { super.dispose(); this.#$instanceContent_.remove(); this.#$instanceContent_ = null; this.#$instancePopper_.remove(); this.#$instancePopper_ = null; this.#$content_.empty(); this.#$content_ = null; for (let id in this.#ids_) { this.remove(id); } this.#singleton_.destroy(); this.#singleton_ = null; this.#menuItems_ = null; this.#ids_ = null; this.#instanceIds_ = null; this.#activeInstance_ = null; } } Mixly.DropdownMenuGroup = DropdownMenuGroup; });