"use strict"; const $ = require("jquery"); const templates = require("../views"); let contextMenu, contextMenuContainer; module.exports = class ContextMenu { constructor(contextMenuItems, contextMenuActions, selectedElement, event) { this.contextMenuItems = contextMenuItems; this.contextMenuActions = contextMenuActions; this.selectedElement = selectedElement; this.event = event; contextMenuContainer = $("#context-menu-container"); contextMenu = $("#context-menu"); } show() { showContextMenu(this.contextMenuItems, this.selectedElement, this.event); this.bindEvents(); return false; } bindEvents() { const contextMenuActions = this.contextMenuActions; contextMenuActions.execute = (id, ...args) => contextMenuActions[id] && contextMenuActions[id](...args); contextMenu.find(".context-menu-item").on("click", function() { const $this = $(this); const itemData = $this.attr("data-data"); const contextAction = $this.attr("data-action"); contextMenuActions.execute(contextAction, itemData); }); } }; function showContextMenu(contextMenuItems, selectedElement, event) { const target = $(event.currentTarget); let output = ""; for (const item of contextMenuItems) { if (item.check(target)) { if (item.divider) { output += templates.contextmenu_divider(); } else { output += templates.contextmenu_item({ class: typeof item.className === "function" ? item.className(target) : item.className, action: item.actionId, text: typeof item.displayName === "function" ? item.displayName(target) : item.displayName, data: typeof item.data === "function" ? item.data(target) : item.data, }); } } } contextMenuContainer.show(); contextMenu .html(output) .css(positionContextMenu(selectedElement, event)); } function positionContextMenu(selectedElement, e) { let offset; const menuWidth = contextMenu.outerWidth(); const menuHeight = contextMenu.outerHeight(); if (selectedElement.hasClass("menu")) { offset = selectedElement.offset(); offset.left -= menuWidth - selectedElement.outerWidth(); offset.top += selectedElement.outerHeight(); return offset; } offset = {left: e.pageX, top: e.pageY}; if ((window.innerWidth - offset.left) < menuWidth) { offset.left = window.innerWidth - menuWidth; } if ((window.innerHeight - offset.top) < menuHeight) { offset.top = window.innerHeight - menuHeight; } return offset; }