mj-context-menu
Version:
A generic context menu
131 lines • 3.51 kB
JavaScript
import { AbstractPostable } from './abstract_postable.js';
import { AbstractItem } from './abstract_item.js';
import { HtmlClasses } from './html_classes.js';
import { Submenu } from './item_submenu.js';
export class AbstractMenu extends AbstractPostable {
constructor() {
super(...arguments);
this.className = HtmlClasses['CONTEXTMENU'];
this.role = 'menu';
this._items = [];
this._baseMenu = null;
}
set baseMenu(menu) {
this._baseMenu = menu;
}
get baseMenu() {
return this._baseMenu;
}
get items() {
return this._items;
}
set items(items) {
this._items = items;
}
get pool() {
return this.variablePool;
}
get focused() {
return this._focused;
}
set focused(item) {
if (this._focused === item) {
return;
}
if (!this._focused) {
this.unfocus();
}
const old = this._focused;
this._focused = item;
if (old) {
old.unfocus();
}
}
up(_event) {
const items = this.items.filter((x) => x instanceof AbstractItem && !x.isHidden());
if (items.length === 0) {
return;
}
if (!this.focused) {
items[items.length - 1].focus();
return;
}
let index = items.indexOf(this.focused);
if (index === -1) {
return;
}
index = index ? --index : items.length - 1;
items[index].focus();
}
down(_event) {
const items = this.items.filter((x) => x instanceof AbstractItem && !x.isHidden());
if (items.length === 0) {
return;
}
if (!this.focused) {
items[0].focus();
return;
}
let index = items.indexOf(this.focused);
if (index === -1) {
return;
}
index++;
index = index === items.length ? 0 : index;
items[index].focus();
}
generateHtml() {
super.generateHtml();
this.generateMenu();
}
generateMenu() {
const html = this.html;
html.classList.add(HtmlClasses['MENU']);
for (const item of this.items) {
if (!item.isHidden()) {
html.appendChild(item.html);
continue;
}
const itemHtml = item.html;
if (itemHtml.parentNode) {
itemHtml.parentNode.removeChild(itemHtml);
}
}
}
post(x, y) {
this.variablePool.update();
super.post(x, y);
}
unpostSubmenus() {
const submenus = this.items.filter((x) => x instanceof Submenu);
for (const submenu of submenus) {
submenu.submenu.unpost();
if (submenu !== this.focused) {
submenu.unfocus();
}
}
}
unpost() {
super.unpost();
this.unpostSubmenus();
this.focused = null;
}
find(id) {
for (const item of this.items) {
if (item.type === 'rule') {
continue;
}
if (item.id === id) {
return item;
}
if (item.type === 'submenu') {
const result = item.submenu.find(id);
if (result) {
return result;
}
}
}
return null;
}
}
//# sourceMappingURL=abstract_menu.js.map