138 lines
3.6 KiB
TypeScript
138 lines
3.6 KiB
TypeScript
var ContextMenu = new class ContextMenu {
|
|
elements: {
|
|
menu: HTMLDivElement;
|
|
|
|
items: {
|
|
copy: HTMLDivElement;
|
|
paste: HTMLDivElement;
|
|
cut: HTMLDivElement;
|
|
ghost: HTMLDivElement;
|
|
osc: HTMLDivElement;
|
|
http: HTMLDivElement;
|
|
};
|
|
};
|
|
|
|
open: boolean;
|
|
contextHolder: HTMLElement;
|
|
|
|
constructor() {
|
|
this.elements = {
|
|
menu: document.querySelector('.contextmenu'),
|
|
items: {
|
|
copy: document.querySelector('.contextmenu').querySelector('.copy'),
|
|
paste: document.querySelector('.contextmenu').querySelector('.paste'),
|
|
cut: document.querySelector('.contextmenu').querySelector('.cut'),
|
|
ghost: document.querySelector('.contextmenu').querySelector('.ghost'),
|
|
osc: document.querySelector('.contextmenu').querySelector('.osc'),
|
|
http: document.querySelector('.contextmenu').querySelector('.http')
|
|
}
|
|
};
|
|
|
|
this.open = false;
|
|
this.contextHolder = null;
|
|
|
|
window.addEventListener('contextmenu', (ev: MouseEvent) => this.handle(this.elements.menu, ev));
|
|
window.addEventListener('mousedown', (ev: MouseEvent) => {
|
|
if (this.open == true)
|
|
if (ev.target) {
|
|
var target = ev.target as HTMLElement;
|
|
|
|
if (
|
|
target.classList.contains('contextmenu') ||
|
|
(target.parentElement != undefined && target.parentElement.classList.contains('contextmenu'))
|
|
) {
|
|
} else {
|
|
this.close();
|
|
}
|
|
} else this.close();
|
|
});
|
|
}
|
|
|
|
setItems(items: DropdownItemTypes[]) {
|
|
for (var type in this.elements.items) {
|
|
if (items.includes(<DropdownItemTypes>type)) this.elements.items[type].style.display = 'block';
|
|
else this.elements.items[type].style.display = 'none';
|
|
}
|
|
}
|
|
|
|
close() {
|
|
this.elements.menu.style.display = 'none';
|
|
if (this.contextHolder != null) {
|
|
this.contextHolder.classList.remove('context');
|
|
this.contextHolder = null;
|
|
}
|
|
this.open = false;
|
|
}
|
|
|
|
handle(menu: HTMLDivElement, ev: MouseEvent) {
|
|
if (ev.target != undefined) {
|
|
var target = ev.target as HTMLElement;
|
|
|
|
var types = {
|
|
key: (element: HTMLElement) => {
|
|
if (element.hasAttribute('x') && element.hasAttribute('y')) {
|
|
var keyX = element.getAttribute('x');
|
|
var keyY = element.getAttribute('y');
|
|
|
|
var items: DropdownItemTypes[] = [
|
|
'osc',
|
|
'http'
|
|
];
|
|
if (PageHandler.currentPage.keys[keyY][keyX].state.type != 'empty') items.push('copy', 'cut');
|
|
if (PageHandler.currentPage.keys[keyY][keyX].state.type == 'custom') items.push('ghost');
|
|
if (UndeckedClipboard.hasKeyInClipboard()) items.push('paste');
|
|
|
|
this.setItems(items);
|
|
|
|
this.elements.items.copy.onclick = () => {
|
|
UndeckedClipboard.copyKey(parseInt(keyX), parseInt(keyY));
|
|
this.close();
|
|
};
|
|
|
|
this.elements.items.cut.onclick = () => {
|
|
UndeckedClipboard.cutKey(parseInt(keyX), parseInt(keyY));
|
|
this.close();
|
|
};
|
|
|
|
this.elements.items.paste.onclick = () => {
|
|
UndeckedClipboard.pasteKey(parseInt(keyX), parseInt(keyY));
|
|
this.close();
|
|
};
|
|
|
|
this.elements.items.ghost.onclick = () => {
|
|
UndeckedClipboard.copyGhostKey(parseInt(keyX), parseInt(keyY));
|
|
this.close();
|
|
};
|
|
|
|
return items.length > 0;
|
|
}
|
|
}
|
|
};
|
|
|
|
for (var type in types)
|
|
if (target.classList.contains(type)) {
|
|
ev.preventDefault();
|
|
|
|
var valid = types[type](target);
|
|
|
|
if (valid) {
|
|
this.contextHolder = target;
|
|
target.classList.add('context');
|
|
|
|
setTimeout(() => {
|
|
this.open = true;
|
|
}, 100);
|
|
|
|
menu.style.left = `${ev.pageX}px`;
|
|
menu.style.top = `${ev.pageY - 50}px`;
|
|
menu.style.display = 'block';
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}();
|
|
|
|
type DropdownItemTypes = 'copy' | 'paste' | 'cut' | 'ghost' | 'osc' | 'http';
|