From 18377d0e9fa16c86e489664a6de9b031dee3e2bf Mon Sep 17 00:00:00 2001 From: Vanessa Date: Wed, 13 Aug 2025 10:46:35 +0800 Subject: [PATCH] :art: https://github.com/siyuan-note/siyuan/issues/15554 --- app/src/protyle/wysiwyg/enter.ts | 19 +++++++++++++------ app/src/protyle/wysiwyg/input.ts | 21 ++++++++++++--------- app/src/protyle/wysiwyg/keydown.ts | 4 ++-- app/src/protyle/wysiwyg/remove.ts | 17 +++++++++++++++++ 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/app/src/protyle/wysiwyg/enter.ts b/app/src/protyle/wysiwyg/enter.ts index 3ab784650..60f500574 100644 --- a/app/src/protyle/wysiwyg/enter.ts +++ b/app/src/protyle/wysiwyg/enter.ts @@ -52,11 +52,14 @@ export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle if (blockElement.getAttribute("data-type") === "NodeAttributeView") { return true; } - // 代码块 - const trimStartText = editableElement.innerHTML.trimStart(); - if (trimStartText.startsWith("```") || trimStartText.startsWith("···") || trimStartText.startsWith("~~~") || - trimStartText.indexOf("\n```") > -1 || trimStartText.indexOf("\n~~~") > -1 || trimStartText.indexOf("\n···") > -1) { - if (trimStartText.indexOf("\n") === -1 && trimStartText.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { + + const trimStartHTML = editableElement.innerHTML.trimStart(); + const trimStartText = editableElement.textContent.trimStart(); + if (trimStartHTML.startsWith("```") || trimStartHTML.startsWith("···") || trimStartHTML.startsWith("~~~") || + (trimStartHTML.indexOf("\n```") > -1 && trimStartText.indexOf("\n```") > -1) || + (trimStartHTML.indexOf("\n~~~") > -1 && trimStartText.indexOf("\n~~~") > -1) || + (trimStartHTML.indexOf("\n···") > -1 && trimStartText.indexOf("\n···") > -1)) { + if (trimStartHTML.indexOf("\n") === -1 && trimStartHTML.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { // ```test` 不处理,正常渲染为段落块 } else if (blockElement.classList.contains("p")) { // https://github.com/siyuan-note/siyuan/issues/6953 const oldHTML = blockElement.outerHTML; @@ -93,6 +96,7 @@ export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle return true; } } + // 代码块 if (blockElement.getAttribute("data-type") === "NodeCodeBlock") { const wbrElement = document.createElement("wbr"); range.insertNode(wbrElement); @@ -224,9 +228,12 @@ export const enter = (blockElement: HTMLElement, range: Range, protyle: IProtyle selectWbrElement.parentElement.outerHTML = ""; } const newHTML = newEditableElement.innerHTML.trimStart(); + const newText = newEditableElement.textContent.trimStart(); // https://github.com/siyuan-note/siyuan/issues/10759 if (newHTML.startsWith("```") || newHTML.startsWith("···") || newHTML.startsWith("~~~") || - newHTML.indexOf("\n```") > -1 || newHTML.indexOf("\n~~~") > -1 || newHTML.indexOf("\n···") > -1) { + (newHTML.indexOf("\n```") > -1 && newText.indexOf("\n```") > -1) || + (newHTML.indexOf("\n~~~") > -1 && newText.indexOf("\n~~~") > -1) || + (newHTML.indexOf("\n···") > -1 && newText.indexOf("\n···") > -1)) { if (newHTML.indexOf("\n") === -1 && newHTML.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { // ```test` 不处理,正常渲染为段落块 } else { diff --git a/app/src/protyle/wysiwyg/input.ts b/app/src/protyle/wysiwyg/input.ts index c5629da9f..21105e8c9 100644 --- a/app/src/protyle/wysiwyg/input.ts +++ b/app/src/protyle/wysiwyg/input.ts @@ -109,12 +109,13 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: )) { editElement.innerHTML = editElement.innerHTML.replace("》", ">"); } - const trimStartText = editElement.innerHTML.trimStart(); - if ((trimStartText.startsWith("````") || trimStartText.startsWith("····") || trimStartText.startsWith("~~~~")) && - trimStartText.indexOf("\n") === -1) { + const trimStartHTML = editElement.innerHTML.trimStart(); + const trimStartText = editElement.textContent.trimStart(); + if ((trimStartHTML.startsWith("````") || trimStartHTML.startsWith("····") || trimStartHTML.startsWith("~~~~")) && + trimStartHTML.indexOf("\n") === -1) { // 超过三个标记符就可以形成为代码块,下方会处理 - } else if ((trimStartText.startsWith("```") || trimStartText.startsWith("···") || trimStartText.startsWith("~~~")) && - trimStartText.indexOf("\n") === -1 && trimStartText.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") === -1) { + } else if ((trimStartHTML.startsWith("```") || trimStartHTML.startsWith("···") || trimStartHTML.startsWith("~~~")) && + trimStartHTML.indexOf("\n") === -1 && trimStartHTML.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") === -1) { // ```test` 后续处理,```test 不处理 updateTransaction(protyle, id, blockElement.outerHTML, protyle.wysiwyg.lastHTMLs[id]); wbrElement.remove(); @@ -124,7 +125,7 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: if (type === "NodeParagraph" && ( editElement.innerHTML.startsWith("¥¥") || editElement.innerHTML.startsWith("¥¥") || // https://ld246.com/article/1730020516427 - trimStartText.indexOf("\n¥¥") > -1 || trimStartText.indexOf("\n¥¥") > -1 + trimStartHTML.indexOf("\n¥¥") > -1 || trimStartHTML.indexOf("\n¥¥") > -1 )) { editElement.innerHTML = editElement.innerHTML.replace("¥¥", "$$$$").replace("¥¥", "$$$$"); } @@ -153,10 +154,12 @@ export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: } } else { if (type !== "NodeCodeBlock" && ( - trimStartText.startsWith("```") || trimStartText.startsWith("~~~") || trimStartText.startsWith("···") || - trimStartText.indexOf("\n```") > -1 || trimStartText.indexOf("\n~~~") > -1 || trimStartText.indexOf("\n···") > -1 + trimStartHTML.startsWith("```") || trimStartHTML.startsWith("~~~") || trimStartHTML.startsWith("···") || + (trimStartHTML.indexOf("\n```") > -1 && trimStartText.indexOf("\n```") > -1) || + (trimStartHTML.indexOf("\n~~~") > -1 && trimStartText.indexOf("\n~~~") > -1) || + (trimStartHTML.indexOf("\n···") > -1 && trimStartText.indexOf("\n···") > -1) )) { - if (trimStartText.indexOf("\n") === -1 && trimStartText.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { + if (trimStartHTML.indexOf("\n") === -1 && trimStartHTML.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { // ```test` 不处理,正常渲染为段落块 } else { let replaceInnerHTML = editElement.innerHTML.trim().replace(/^(~|·|`){3,}/g, "```").replace(/\n(~|·|`){3,}/g, "\n```").trim(); diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 5fee2d41d..e890050bb 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -691,8 +691,8 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { } else { // 修正光标上移至 \n 结尾的块时落点错误 https://github.com/siyuan-note/siyuan/issues/14443 const prevEditableElement = getContenteditableElement(previousElement) as HTMLElement; - if (prevEditableElement && prevEditableElement.lastChild.nodeType === 3 && - prevEditableElement.lastChild.textContent.endsWith("\n")) { + if (prevEditableElement && prevEditableElement.lastChild?.nodeType === 3 && + prevEditableElement.lastChild?.textContent.endsWith("\n")) { // 不能移除 /n, 否则两个 /n 导致界面异常 focusBlock(previousElement, undefined, false); event.preventDefault(); diff --git a/app/src/protyle/wysiwyg/remove.ts b/app/src/protyle/wysiwyg/remove.ts index c9e252df7..61501fd70 100644 --- a/app/src/protyle/wysiwyg/remove.ts +++ b/app/src/protyle/wysiwyg/remove.ts @@ -453,6 +453,23 @@ export const removeBlock = async (protyle: IProtyle, blockElement: Element, rang range.selectNodeContents(previousLastEditElement); range.collapse(false); range.insertNode(leftNodes); + const previousHTML = previousLastEditElement.innerHTML.trimStart(); + const previousText = previousLastEditElement.textContent.trimStart(); + // https://github.com/siyuan-note/siyuan/issues/15554 + if (previousHTML.startsWith("```") || previousHTML.startsWith("···") || previousHTML.startsWith("~~~") || + (previousHTML.indexOf("\n```") > -1 && previousText.indexOf("\n```") > -1) || + (previousHTML.indexOf("\n~~~") > -1 && previousText.indexOf("\n~~~") > -1) || + (previousHTML.indexOf("\n···") > -1 && previousText.indexOf("\n···") > -1)) { + if (previousHTML.indexOf("\n") === -1 && previousHTML.replace(/·|~/g, "`").replace(/^`{3,}/g, "").indexOf("`") > -1) { + // ```test` 不处理,正常渲染为段落块 + } else { + let replaceNewHTML = previousLastEditElement.innerHTML.replace(/\n(~|·|`){3,}/g, "\n```").trim().replace(/^(~|·|`){3,}/g, "```"); + if (!replaceNewHTML.endsWith("\n```")) { + replaceNewHTML += "\n```"; + } + previousLastEditElement.innerHTML = replaceNewHTML; + } + } // 图片前删除到上一个文字块时,图片前有 zwsp previousLastElement.outerHTML = protyle.lute.SpinBlockDOM(previousLastElement.outerHTML); mathRender(getPreviousBlock(removeElement) as HTMLElement);