diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts index 2b9e34a6f..9b8069c73 100644 --- a/app/src/protyle/toolbar/index.ts +++ b/app/src/protyle/toolbar/index.ts @@ -1614,5 +1614,3 @@ export class Toolbar { }); } } - - diff --git a/app/src/protyle/toolbar/util.ts b/app/src/protyle/toolbar/util.ts index 2b8171565..69a2a5482 100644 --- a/app/src/protyle/toolbar/util.ts +++ b/app/src/protyle/toolbar/util.ts @@ -12,3 +12,48 @@ export const previewTemplate = (pathString: string, element: Element, parentId: element.innerHTML = `
${response.data.content.replace(/contenteditable="true"/g, "")}
`; }); }; + +const mergeElement = (a: Element, b: Element, after = true) => { + a.setAttribute("data-type", a.getAttribute("data-type").replace("search-mark", "").trim()); + b.setAttribute("data-type", b.getAttribute("data-type").replace("search-mark", "").trim()); + const attributes = a.attributes + let isMatch = true + for (let i = 0; i < attributes.length; i++) { + if (b.getAttribute(attributes[i].name) !== attributes[i].value) { + isMatch = false + } + } + + if (isMatch) { + if (after) { + a.innerHTML = a.innerHTML + b.innerHTML + } else { + a.innerHTML = b.innerHTML + a.innerHTML + } + b.remove(); + } + return isMatch; +} + +export const removeSearchMark = (element: HTMLElement) => { + let previousElement = element.previousSibling as HTMLElement; + while (previousElement && previousElement.nodeType !== 3) { + if (!mergeElement(element, previousElement, false)) { + break; + } else { + previousElement = element.previousSibling as HTMLElement; + } + } + let nextElement = element.nextSibling as HTMLElement; + while (nextElement && nextElement.nodeType !== 3) { + if (!mergeElement(element, nextElement)) { + break; + } else { + nextElement = element.nextSibling as HTMLElement; + } + } + + if (element.getAttribute("data-type").includes("search-mark")) { + element.setAttribute("data-type", element.getAttribute("data-type").replace("search-mark", "").trim()); + } +} diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 8ea603f5c..c7119c332 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -61,6 +61,7 @@ import {setTableAlign} from "../util/table"; import {countBlockWord, countSelectWord} from "../../layout/status"; import {showMessage} from "../../dialog/message"; import {getBacklinkHeadingMore, loadBreadcrumb} from "./renderBacklink"; +import {removeSearchMark} from "../toolbar/util"; export class WYSIWYG { public lastHTMLs: { [key: string]: string } = {}; @@ -1181,6 +1182,9 @@ export class WYSIWYG { protyle.toolbar.range = getEditorRange(protyle.element); if (target.tagName === "SPAN" && !protyle.disabled) { // https://ld246.com/article/1665141518103 const types = protyle.toolbar.getCurrentType(protyle.toolbar.range); + if (types.length > 0) { + removeSearchMark(target); + } if (types.includes("block-ref")) { refMenu(protyle, target); // 阻止 popover @@ -1189,20 +1193,16 @@ export class WYSIWYG { target.removeAttribute("prevent-popover"); }, 620); return false; - } - if (types.includes("file-annotation-ref")) { + } else if (types.includes("file-annotation-ref")) { protyle.toolbar.showFileAnnotationRef(protyle, target); return false; - } - if (types.includes("tag")) { + } else if (types.includes("tag")) { tagMenu(protyle, target); return false; - } - if (types.includes("inline-memo")) { + } else if (types.includes("inline-memo")) { protyle.toolbar.showRender(protyle, target); return false; - } - if (types.includes("a")) { + } else if (types.includes("a")) { linkMenu(protyle, target); if (window.siyuan.config.editor.floatWindowMode === 0 && target.getAttribute("data-href")?.startsWith("siyuan://blocks")) { diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index a1830fb70..92f18cb1b 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -71,6 +71,7 @@ import {getSavePath} from "../../util/newFile"; import {escapeHtml} from "../../util/escape"; import {insertHTML} from "../util/insertHTML"; import {quickMakeCard} from "../../card/makeCard"; +import {removeSearchMark} from "../toolbar/util"; export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { editorElement.addEventListener("keydown", (event: KeyboardEvent & { target: HTMLElement }) => { @@ -526,6 +527,10 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { const inlineElement = hasClosestByAttribute(range.startContainer, "data-type", null); if (inlineElement) { const types = inlineElement.getAttribute("data-type").split(" "); + if (types.length > 0) { + protyle.toolbar.range = range; + removeSearchMark(inlineElement); + } if (types.includes("block-ref")) { refMenu(protyle, inlineElement); return;