import {Menu} from "../../../plugin/Menu"; import {unicode2Emoji} from "../../../emoji"; import {transaction} from "../../wysiwyg/transaction"; import {openMenuPanel} from "./openMenuPanel"; import {focusBlock} from "../../util/selection"; import {Constants} from "../../../constants"; import {upDownHint} from "../../../util/upDownHint"; import {avRender} from "./render"; export const openViewMenu = (options: { protyle: IProtyle, blockElement: HTMLElement, element: HTMLElement }) => { if (options.protyle.disabled) { return; } const menu = new Menu("av-view"); if (menu.isOpen) { return; } menu.addItem({ icon: "iconEdit", label: window.siyuan.languages.rename, click() { document.querySelector(".av__panel")?.remove(); openMenuPanel({ protyle: options.protyle, blockElement: options.blockElement, type: "config", cb: (avPanelElement) => { (avPanelElement.querySelector('.b3-text-field[data-type="name"]') as HTMLInputElement).focus(); } }); } }); menu.addItem({ icon: "iconSettings", label: window.siyuan.languages.config, click() { document.querySelector(".av__panel")?.remove(); openMenuPanel({ protyle: options.protyle, blockElement: options.blockElement, type: "config" }); } }); menu.addSeparator(); menu.addItem({ icon: "iconCopy", label: window.siyuan.languages.duplicate, click() { document.querySelector(".av__panel")?.remove(); const id = Lute.NewNodeID(); transaction(options.protyle, [{ action: "duplicateAttrViewView", avID: options.blockElement.dataset.avId, previousID: options.element.dataset.id, id, blockID: options.blockElement.dataset.nodeId }], [{ action: "removeAttrViewView", avID: options.blockElement.dataset.avId, id, blockID: options.blockElement.dataset.nodeId }]); options.blockElement.setAttribute(Constants.CUSTOM_SY_AV_VIEW, id); } }); if (options.blockElement.querySelectorAll(".layout-tab-bar .item").length > 1) { menu.addItem({ icon: "iconTrashcan", label: window.siyuan.languages.delete, click() { document.querySelector(".av__panel")?.remove(); transaction(options.protyle, [{ action: "removeAttrViewView", avID: options.blockElement.dataset.avId, id: options.element.dataset.id, blockID: options.blockElement.dataset.nodeId }]); } }); } const rect = options.element.getBoundingClientRect(); menu.open({ x: rect.left, y: rect.bottom }); }; export const bindViewEvent = (options: { protyle: IProtyle, data: IAV, menuElement: HTMLElement blockElement: Element }) => { const inputElement = options.menuElement.querySelector('.b3-text-field[data-type="name"]') as HTMLInputElement; inputElement.addEventListener("blur", () => { if (inputElement.value !== inputElement.dataset.value) { transaction(options.protyle, [{ action: "setAttrViewViewName", avID: options.data.id, id: options.data.viewID, data: inputElement.value }], [{ action: "setAttrViewViewName", avID: options.data.id, id: options.data.viewID, data: inputElement.dataset.value }]); inputElement.dataset.value = inputElement.value; } }); inputElement.addEventListener("keydown", (event) => { if (event.isComposing) { return; } if (event.key === "Enter") { event.preventDefault(); inputElement.blur(); options.menuElement.parentElement.remove(); } }); inputElement.select(); const toggleTitleElement = options.menuElement.querySelector('.b3-switch[data-type="toggle-view-title"]') as HTMLInputElement; toggleTitleElement.addEventListener("change", () => { const avID = options.blockElement.getAttribute("data-av-id"); const blockID = options.blockElement.getAttribute("data-node-id"); if (!toggleTitleElement.checked) { // hide transaction(options.protyle, [{ action: "hideAttrViewName", avID, blockID, data: true }], [{ action: "hideAttrViewName", avID, blockID, data: false }]); options.blockElement.querySelector(".av__title").classList.add("fn__none"); } else { transaction(options.protyle, [{ action: "hideAttrViewName", avID, blockID, data: false }], [{ action: "hideAttrViewName", avID, blockID, data: true }]); options.blockElement.querySelector(".av__title").classList.remove("fn__none"); } }); }; export const getViewHTML = (data: IAV) => { const view = data.view; return `
`; }; export const bindSwitcherEvent = (options: { protyle: IProtyle, menuElement: Element, blockElement: Element }) => { const inputElement = options.menuElement.querySelector(".b3-text-field") as HTMLInputElement; inputElement.focus(); inputElement.addEventListener("keydown", (event) => { event.stopPropagation(); if (event.isComposing) { return; } upDownHint(options.menuElement.querySelector(".fn__flex-1"), event, "b3-menu__item--current"); if (event.key === "Enter") { const currentElement = options.menuElement.querySelector(".b3-menu__item--current") as HTMLElement; if (currentElement) { options.blockElement.removeAttribute("data-render"); avRender(options.blockElement, options.protyle, undefined, currentElement.dataset.id); options.menuElement.remove(); focusBlock(options.blockElement); } } else if (event.key === "Escape") { options.menuElement.remove(); focusBlock(options.blockElement); } }); inputElement.addEventListener("input", (event: InputEvent) => { if (event.isComposing) { return; } filterSwitcher(options.menuElement); }); inputElement.addEventListener("compositionend", () => { filterSwitcher(options.menuElement); }); }; const filterSwitcher = (menuElement: Element) => { const inputElement = menuElement.querySelector(".b3-text-field") as HTMLInputElement; const key = inputElement.value; menuElement.querySelectorAll('.b3-menu__item[draggable="true"]').forEach(item => { if (!key || (key.toLowerCase().indexOf(item.textContent.trim().toLowerCase()) > -1 || item.textContent.trim().toLowerCase().indexOf(key.toLowerCase()) > -1)) { item.classList.remove("fn__none"); } else { item.classList.add("fn__none"); item.classList.remove("b3-menu__item--current"); } }); if (!menuElement.querySelector(".b3-menu__item--current")) { menuElement.querySelector(".fn__flex-1 .b3-menu__item:not(.fn__none)")?.classList.add("b3-menu__item--current"); } }; export const getSwitcherHTML = (views: IAVView[], viewId: string) => { let html = ""; views.forEach((item) => { html += ``; }); return ``; }; export const addView = (protyle: IProtyle, blockElement: Element) => { const id = Lute.NewNodeID(); const avID = blockElement.getAttribute("data-av-id"); transaction(protyle, [{ action: "addAttrViewView", avID, id, blockID: blockElement.getAttribute("data-node-id") }], [{ action: "removeAttrViewView", avID, id, blockID: blockElement.getAttribute("data-node-id") }]); blockElement.setAttribute(Constants.CUSTOM_SY_AV_VIEW, id); };