diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 4d3e4fcd5..8ae9b4fb2 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -248,10 +248,9 @@ export const fileAnnotationRefMenu = (protyle: IProtyle, refElement: HTMLElement label: `${window.siyuan.languages.turnInto} ${window.siyuan.languages.text}`, icon: "iconRefresh", click() { - refElement.outerHTML = `${refElement.innerHTML}`; nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); + removeInlineType(refElement, "file-annotation-ref", protyle.toolbar.range); updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML); - focusByWbr(nodeElement, protyle.toolbar.range); oldHTML = nodeElement.outerHTML; } }).element); @@ -477,10 +476,9 @@ export const refMenu = (protyle: IProtyle, element: HTMLElement) => { submenu = submenu.concat([{ label: window.siyuan.languages.text, click() { - element.outerHTML = `${element.innerHTML}`; nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); + removeInlineType(element, "block-ref", protyle.toolbar.range); updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML); - focusByWbr(nodeElement, protyle.toolbar.range); oldHTML = nodeElement.outerHTML; } }, { @@ -1100,8 +1098,9 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText } hideElements(["util", "toolbar", "hint"], protyle); const id = nodeElement.getAttribute("data-node-id"); - const html = nodeElement.outerHTML; + let html = nodeElement.outerHTML; const linkAddress = linkElement.getAttribute("data-href"); + let inputElements: NodeListOf window.siyuan.menus.menu.append(new MenuItem({ iconHTML: "", type: "readonly", @@ -1115,7 +1114,7 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText `, bind(element) { element.style.maxWidth = "none"; - const inputElements = element.querySelectorAll("textarea"); + inputElements = element.querySelectorAll("textarea"); inputElements[0].value = Lute.UnEscapeHTMLStr(linkAddress) || ""; inputElements[0].addEventListener("keydown", (event) => { if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) { @@ -1202,14 +1201,6 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText } }).element); } - window.siyuan.menus.menu.append(new MenuItem({ - label: `${window.siyuan.languages.turnInto} ${window.siyuan.languages.text}`, - icon: "iconRefresh", - click() { - removeInlineType(linkElement, protyle.toolbar.range); - updateTransaction(protyle, id, nodeElement.outerHTML, html); - } - }).element); if (linkAddress?.startsWith("siyuan://blocks/")) { window.siyuan.menus.menu.append(new MenuItem({ label: `${window.siyuan.languages.turnInto} ${window.siyuan.languages.ref}`, @@ -1220,7 +1211,9 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText types.push("block-ref"); types.splice(types.indexOf("a"), 1); linkElement.setAttribute("data-type", types.join(" ")); - linkElement.setAttribute("data-id", linkAddress?.replace("siyuan://blocks/", "")); + linkElement.setAttribute("data-id", inputElements[0].value.replace("siyuan://blocks/", "")); + inputElements[0].value = ""; + inputElements[2].value = ""; linkElement.removeAttribute("data-href"); linkElement.removeAttribute("data-title"); nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); @@ -1228,19 +1221,32 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText protyle.toolbar.range.selectNode(linkElement); protyle.toolbar.range.collapse(false); focusByRange(protyle.toolbar.range); + html = nodeElement.outerHTML; } }).element); } + window.siyuan.menus.menu.append(new MenuItem({ + label: `${window.siyuan.languages.turnInto} ${window.siyuan.languages.text}`, + icon: "iconRefresh", + click() { + inputElements[0].value = ""; + inputElements[2].value = ""; + nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); + removeInlineType(linkElement, "a", protyle.toolbar.range); + updateTransaction(protyle, id, nodeElement.outerHTML, html); + html = nodeElement.outerHTML; + } + }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: "iconTrashcan", label: window.siyuan.languages.remove, click() { - const oldHTML = nodeElement.outerHTML; linkElement.insertAdjacentHTML("afterend", ""); linkElement.remove(); nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); - updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML); + updateTransaction(protyle, id, nodeElement.outerHTML, html); focusByWbr(nodeElement, protyle.toolbar.range); + html = nodeElement.outerHTML; } }).element); if (protyle?.app?.plugins) { @@ -1261,29 +1267,34 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText h: 26 }); window.siyuan.menus.menu.element.setAttribute("data-from", hasClosestByClassName(protyle.element, "block__edit") ? "popover" : "app"); - const textElements = window.siyuan.menus.menu.element.querySelectorAll("textarea"); if (focusText || protyle.lute.IsValidLinkDest(linkAddress)) { - textElements[1].select(); + inputElements[1].select(); } else { - textElements[0].select(); + inputElements[0].select(); } window.siyuan.menus.menu.removeCB = () => { - if (textElements[2].value) { - linkElement.setAttribute("data-title", Lute.EscapeHTMLStr(textElements[2].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""))); + if (inputElements[2].value) { + linkElement.setAttribute("data-title", Lute.EscapeHTMLStr(inputElements[2].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""))); } else { linkElement.removeAttribute("data-title"); } - linkElement.setAttribute("data-href", Lute.EscapeHTMLStr(textElements[0].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""))); + if (inputElements[0].value) { + linkElement.setAttribute("data-href", Lute.EscapeHTMLStr(inputElements[0].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""))); + } else if (linkElement.getAttribute("data-type").indexOf("a") === -1) { + linkElement.removeAttribute("data-href"); + } const currentRange = getSelection().rangeCount === 0 ? undefined : getSelection().getRangeAt(0); if (linkElement.textContent === "" || linkElement.textContent === Constants.ZWSP) { - removeInlineType(linkElement, (currentRange && !protyle.element.contains(currentRange.startContainer)) ? protyle.toolbar.range : undefined); + removeInlineType(linkElement, "a", (currentRange && !protyle.element.contains(currentRange.startContainer)) ? protyle.toolbar.range : undefined); } else if (currentRange && !protyle.element.contains(currentRange.startContainer)) { protyle.toolbar.range.selectNodeContents(linkElement); protyle.toolbar.range.collapse(false); focusByRange(protyle.toolbar.range); } - nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); - updateTransaction(protyle, id, nodeElement.outerHTML, html); + if (html !== nodeElement.outerHTML) { + nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); + updateTransaction(protyle, id, nodeElement.outerHTML, html); + } }; }; diff --git a/app/src/protyle/toolbar/util.ts b/app/src/protyle/toolbar/util.ts index 5a8502a9a..64d9dd508 100644 --- a/app/src/protyle/toolbar/util.ts +++ b/app/src/protyle/toolbar/util.ts @@ -64,25 +64,32 @@ export const removeSearchMark = (element: HTMLElement) => { } }; -export const removeInlineType = (linkElement: HTMLElement, range?: Range) => { - const types = linkElement.getAttribute("data-type").split(" "); +export const removeInlineType = (inlineElement: HTMLElement, type: string, range?: Range) => { + const types = inlineElement.getAttribute("data-type").split(" "); if (types.length === 1) { - const linkParentElement = linkElement.parentElement; - linkElement.outerHTML = linkElement.innerHTML.replace(Constants.ZWSP, "") + ""; + const linkParentElement = inlineElement.parentElement; + inlineElement.outerHTML = inlineElement.innerHTML.replace(Constants.ZWSP, "") + ""; if (range) { focusByWbr(linkParentElement, range); } } else { types.find((itemType, index) => { - if ("a" === itemType) { + if (type === itemType) { types.splice(index, 1); return true; } }); - linkElement.setAttribute("data-type", types.join(" ")); - linkElement.removeAttribute("data-href"); + inlineElement.setAttribute("data-type", types.join(" ")); + if (type === "a") { + inlineElement.removeAttribute("data-href"); + } else if (type === "file-annotation-ref") { + inlineElement.removeAttribute("data-id"); + } else if (type === "block-ref") { + inlineElement.removeAttribute("data-id"); + inlineElement.removeAttribute("data-subtype"); + } if (range) { - range.selectNodeContents(linkElement); + range.selectNodeContents(inlineElement); range.collapse(false); focusByRange(range); }