Просмотр исходного кода

:art: fix https://github.com/siyuan-note/siyuan/issues/8617

Vanessa 2 лет назад
Родитель
Сommit
6e52e78ea4

+ 113 - 0
app/src/menus/protyle.ts

@@ -44,6 +44,104 @@ import {renameTag} from "../util/noRelyPCFunction";
 import {hideElements} from "../protyle/ui/hideElements";
 import {emitOpenMenu} from "../plugin/EventBus";
 
+export const fileAnnotationRefMenu = (protyle: IProtyle, refElement: HTMLElement) => {
+    const nodeElement = hasClosestBlock(refElement);
+    if (!nodeElement) {
+        return;
+    }
+    hideElements(["util", "toolbar", "hint"], protyle);
+    const id = nodeElement.getAttribute("data-node-id");
+    const oldHTML = nodeElement.outerHTML;
+    window.siyuan.menus.menu.remove();
+    let anchorElement: HTMLInputElement;
+    window.siyuan.menus.menu.append(new MenuItem({
+        label: `<input style="margin: 4px 0" class="b3-text-field fn__block" value="${refElement.getAttribute("data-id") || ""}" readonly placeholder="ID">`,
+    }).element);
+    window.siyuan.menus.menu.append(new MenuItem({
+        label: `<input style="margin: 4px 0" class="b3-text-field fn__block" data-type="anchor" placeholder="${window.siyuan.languages.anchor}">`,
+        bind(menuItemElement) {
+            anchorElement = menuItemElement.querySelector("input");
+            anchorElement.value = refElement.textContent;
+            const inputEvent = () => {
+                if (anchorElement.value) {
+                    refElement.innerHTML = Lute.EscapeHTMLStr(anchorElement.value);
+                } else {
+                    refElement.innerHTML = "*";
+                }
+            }
+            anchorElement.addEventListener("input", (event: KeyboardEvent) => {
+                if (event.isComposing) {
+                    return;
+                }
+                inputEvent();
+                event.stopPropagation();
+            });
+            anchorElement.addEventListener("compositionend", (event: KeyboardEvent) => {
+                if (event.isComposing) {
+                    return;
+                }
+                inputEvent();
+                event.stopPropagation();
+            });
+            anchorElement.addEventListener("keydown", (event: KeyboardEvent) => {
+                if (event.isComposing) {
+                    return;
+                }
+                if (event.key === "Enter" && !event.isComposing) {
+                    window.siyuan.menus.menu.remove();
+                } else if (electronUndo(event)) {
+                    return;
+                }
+            });
+        }
+    }).element);
+    window.siyuan.menus.menu.append(new MenuItem({
+        icon: "iconTrashcan",
+        label: window.siyuan.languages.remove,
+        click() {
+            refElement.outerHTML = refElement.textContent + "<wbr>";
+        }
+    }).element);
+
+    if (protyle?.app?.plugins) {
+        emitOpenMenu({
+            plugins: protyle.app.plugins,
+            type: "open-menu-fileannotationref",
+            detail: {
+                protyle,
+                element: refElement,
+            },
+            separatorPosition: "top",
+        });
+    }
+
+    const rect = refElement.getBoundingClientRect();
+    window.siyuan.menus.menu.popup({
+        x: rect.left,
+        y: rect.top + 26,
+        h: 26
+    });
+
+    anchorElement.select();
+    window.siyuan.menus.menu.removeCB = () => {
+        if (nodeElement.outerHTML !== oldHTML) {
+            nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
+            updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
+        }
+
+        const currentRange = getSelection().rangeCount === 0 ? undefined : getSelection().getRangeAt(0);
+        if (currentRange && !protyle.element.contains(currentRange.startContainer)) {
+            if (refElement.parentElement) {
+                protyle.toolbar.range.selectNodeContents(refElement);
+                protyle.toolbar.range.collapse(false);
+                focusByRange(protyle.toolbar.range);
+            } else {
+                focusByWbr(nodeElement, protyle.toolbar.range);
+            }
+        }
+    };
+};
+
 export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
     const nodeElement = hasClosestBlock(element);
     if (!nodeElement) {
@@ -71,6 +169,9 @@ export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
                 element.setAttribute("data-subtype", inputElement.value ? "s" : "d");
             });
             inputElement.addEventListener("keydown", (event) => {
+                if (event.isComposing) {
+                    return;
+                }
                 if (event.key === "Enter" && !event.isComposing) {
                     window.siyuan.menus.menu.remove();
                 } else if (electronUndo(event)) {
@@ -443,6 +544,18 @@ export const contentMenu = (protyle: IProtyle, nodeElement: Element) => {
             }).element);
         }
     }
+    if (protyle?.app?.plugins) {
+        emitOpenMenu({
+            plugins: protyle.app.plugins,
+            type: "open-menu-content",
+            detail: {
+                protyle,
+                range,
+                element: nodeElement,
+            },
+            separatorPosition: "top",
+        });
+    }
 };
 
 export const zoomOut = (options: {

+ 2 - 2
app/src/mobile/util/touch.ts

@@ -3,7 +3,7 @@ import {closePanel} from "./closePanel";
 import {popMenu} from "../menu";
 import {activeBlur, hideKeyboardToolbar} from "./keyboardToolbar";
 import {getCurrentEditor} from "../editor";
-import {linkMenu, refMenu, tagMenu} from "../../menus/protyle";
+import {fileAnnotationRefMenu, linkMenu, refMenu, tagMenu} from "../../menus/protyle";
 
 let clientX: number;
 let clientY: number;
@@ -46,7 +46,7 @@ export const handleTouchEnd = (event: TouchEvent) => {
         if (types.includes("block-ref")) {
             refMenu(editor.protyle, target);
         } else if (types.includes("file-annotation-ref")) {
-            editor.protyle.toolbar.showFileAnnotationRef(editor.protyle, target);
+           fileAnnotationRefMenu(editor.protyle, target);
         } else if (types.includes("tag")) {
             tagMenu(editor.protyle, target);
         } else if (types.includes("a")) {

+ 0 - 81
app/src/protyle/toolbar/index.ts

@@ -754,87 +754,6 @@ export class Toolbar {
         }
     }
 
-    public showFileAnnotationRef(protyle: IProtyle, refElement: HTMLElement) {
-        const nodeElement = hasClosestBlock(refElement);
-        if (!nodeElement) {
-            return;
-        }
-        hideElements(["hint"], protyle);
-        window.siyuan.menus.menu.remove();
-        const id = nodeElement.getAttribute("data-node-id");
-        const html = nodeElement.outerHTML;
-        this.subElement.style.padding = "";
-        this.subElement.innerHTML = `<div class="b3-form__space--small">
-<label class="fn__flex">
-    <span class="ft__on-surface fn__flex-center" style="width: 64px">ID</span>
-    <div class="fn__space"></div>
-    <input data-type="id" value="${refElement.getAttribute("data-id") || ""}" class="b3-text-field fn__block" readonly />
-</label>
-<div class="fn__hr"></div>
-<label class="fn__flex">
-    <span class="ft__on-surface fn__flex-center" style="width: 64px">${window.siyuan.languages.anchor}</span>
-    <div class="fn__space"></div>
-    <input data-type="anchor" class="b3-text-field fn__block" placeholder="${window.siyuan.languages.anchor}" />
-</label>
-<div class="fn__hr"></div>
-<div class="fn__hr"></div>
-<div class="fn__flex"><span class="fn__flex-1"></span>
-    <button class="b3-button b3-button--cancel">${window.siyuan.languages.remove}</button>
-</div></div>`;
-        this.subElement.querySelector(".b3-button--cancel").addEventListener(getEventName(), () => {
-            refElement.outerHTML = refElement.textContent + "<wbr>";
-            hideElements(["util"], protyle);
-        });
-        const anchorElement = this.subElement.querySelector('[data-type="anchor"]') as HTMLInputElement;
-        anchorElement.value = refElement.textContent;
-        anchorElement.addEventListener("input", (event) => {
-            if (anchorElement.value) {
-                refElement.innerHTML = Lute.EscapeHTMLStr(anchorElement.value);
-            } else {
-                refElement.innerHTML = "*";
-            }
-            event.stopPropagation();
-        });
-        anchorElement.addEventListener("keydown", (event: KeyboardEvent) => {
-            event.stopPropagation();
-            if (event.isComposing) {
-                return;
-            }
-            if (event.key === "Enter" || event.key === "Escape") {
-                hideElements(["util"], protyle);
-                event.preventDefault();
-                event.stopPropagation();
-            }
-        });
-        this.subElement.classList.remove("fn__none");
-        this.subElementCloseCB = () => {
-            if (refElement.parentElement) {
-                if (anchorElement.value) {
-                    refElement.innerHTML = Lute.EscapeHTMLStr(anchorElement.value);
-                } else {
-                    refElement.innerHTML = "*";
-                }
-                this.range.setStartAfter(refElement);
-                if (getSelection().rangeCount === 0) {
-                    focusByRange(this.range);
-                }
-            } else {
-                if (getSelection().rangeCount === 0) {
-                    focusByWbr(nodeElement, this.range);
-                }
-            }
-            nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
-            updateTransaction(protyle, id, nodeElement.outerHTML, html);
-        };
-        /// #if !MOBILE
-        this.subElement.style.width = Math.min(480, window.innerWidth) + "px";
-        const nodeRect = refElement.getBoundingClientRect();
-        setPosition(this.subElement, nodeRect.left, nodeRect.bottom, nodeRect.height + 4);
-        /// #endif
-        this.element.classList.add("fn__none");
-        anchorElement.select();
-    }
-
     public showRender(protyle: IProtyle, renderElement: Element, updateElements?: Element[], oldHTML?: string) {
         const nodeElement = hasClosestBlock(renderElement);
         if (!nodeElement) {

+ 11 - 2
app/src/protyle/wysiwyg/index.ts

@@ -20,7 +20,16 @@ import {getSearch, isMobile} from "../../util/functions";
 import {isLocalPath, pathPosix} from "../../util/pathName";
 import {genEmptyElement} from "../../block/util";
 import {previewImage} from "../preview/image";
-import {contentMenu, imgMenu, linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
+import {
+    contentMenu,
+    fileAnnotationRefMenu,
+    imgMenu,
+    linkMenu,
+    refMenu,
+    setFold,
+    tagMenu,
+    zoomOut
+} from "../../menus/protyle";
 import * as dayjs from "dayjs";
 import {dropEvent} from "../util/editorCommonEvent";
 import {input} from "./input";
@@ -1218,7 +1227,7 @@ export class WYSIWYG {
                     }, 620);
                     return false;
                 } else if (types.includes("file-annotation-ref") && !protyle.disabled) {
-                    protyle.toolbar.showFileAnnotationRef(protyle, target);
+                    fileAnnotationRefMenu(protyle, target);
                     return false;
                 } else if (types.includes("tag") && !protyle.disabled) {
                     tagMenu(protyle, target);

+ 2 - 2
app/src/protyle/wysiwyg/keydown.ts

@@ -52,7 +52,7 @@ import {
     goHome,
     upSelect
 } from "./commonHotkey";
-import {linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
+import {fileAnnotationRefMenu, linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
 import {removeEmbed} from "./removeEmbed";
 import {openAttr} from "../../menus/commonMenuItem";
 import {Constants} from "../../constants";
@@ -538,7 +538,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
                         protyle.toolbar.showRender(protyle, inlineElement);
                         return;
                     } else if (types.includes("file-annotation-ref")) {
-                        protyle.toolbar.showFileAnnotationRef(protyle, inlineElement);
+                        fileAnnotationRefMenu(protyle, inlineElement);
                         return;
                     } else if (types.includes("a")) {
                         linkMenu(protyle, inlineElement);