diff --git a/app/src/protyle/markdown/mathRender.ts b/app/src/protyle/markdown/mathRender.ts index 45ad6208a..fc5ee8d2f 100644 --- a/app/src/protyle/markdown/mathRender.ts +++ b/app/src/protyle/markdown/mathRender.ts @@ -87,6 +87,9 @@ export const mathRender = (element: Element, cdn = Constants.PROTYLE_CDN, maxWid // 随着浏览器的升级,从 beforeend 修改为 afterend mathElement.insertAdjacentText("afterend", Constants.ZWSP); } + } else if (nextSibling && nextSibling.nodeType !== 3 && (nextSibling as HTMLElement).getAttribute("data-type")?.indexOf("inline-math") > -1) { + // 相邻的数学公式删除或光标移动有问题 + mathElement.after(document.createTextNode(Constants.ZWSP)); } else if (nextSibling && nextSibling.textContent !== "\n" && // 输入 $a$ 后,光标移动到其他块,再点击 a 后,光标不显示 https://github.com/siyuan-note/insider/issues/1076#issuecomment-1253215515 nextSibling.textContent !== Constants.ZWSP) { diff --git a/app/src/protyle/toolbar/Font.ts b/app/src/protyle/toolbar/Font.ts index 4f975893e..dd782e42b 100644 --- a/app/src/protyle/toolbar/Font.ts +++ b/app/src/protyle/toolbar/Font.ts @@ -177,7 +177,15 @@ export const setFontStyle = (textElement: HTMLElement, textOption: ITextOption) textElement.style.textShadow = "1px 1px var(--b3-border-color), 2px 2px var(--b3-border-color), 3px 3px var(--b3-border-color), 4px 4px var(--b3-border-color)"; break; case "id": - setBlockRef(textOption.color) + setBlockRef(textOption.color); + break; + case "inline-math": + textElement.className = "render-node"; + textElement.setAttribute("contenteditable", "false"); + textElement.setAttribute("data-subtype", "math"); + textElement.setAttribute("data-content", textElement.textContent.replace(Constants.ZWSP, "")); + textElement.removeAttribute("data-render"); + textElement.textContent = ""; break; } } @@ -187,6 +195,9 @@ export const hasSameTextStyle = (currentElement: HTMLElement, sideElement: HTMLE if (!textObj) { return true; } + if (textObj.type === "inline-math") { + return false; + } if (textObj.type === "id") { if (currentElement.nodeType !== 3) { return currentElement.getAttribute("data-id") === sideElement.getAttribute("data-id") && diff --git a/app/src/protyle/toolbar/InlineMath.ts b/app/src/protyle/toolbar/InlineMath.ts index c54c20f53..e0d5840b0 100644 --- a/app/src/protyle/toolbar/InlineMath.ts +++ b/app/src/protyle/toolbar/InlineMath.ts @@ -22,43 +22,32 @@ export class InlineMath extends ToolbarItem { } let mathElement = hasClosestByAttribute(range.startContainer, "data-type", "inline-math") as Element; if (!mathElement && range.startContainer.nodeType !== 3) { - mathElement = (range.startContainer as HTMLElement).querySelector('[data-type="inline-math"]'); + mathElement = (range.startContainer as HTMLElement).querySelector('[data-type~="inline-math"]'); + } + if (!mathElement && range.startOffset === range.startContainer.textContent.length && range.startContainer.nodeType === 3) { + let isMath = true; + range.cloneContents().childNodes.forEach((item: HTMLElement) => { + if ((item.nodeType !== 3 && item.getAttribute("data-type").indexOf("inline-math") > -1) || + (item.nodeType == 3 && item.textContent === "")) { + // 是否仅选中数学公式 + } else { + isMath = false + } + }) + if (isMath) { + const nextSibling = hasNextSibling(range.startContainer) as HTMLElement; + if (nextSibling && nextSibling.nodeType !== 3 && nextSibling.getAttribute("data-type").indexOf("inline-math") > -1) { + mathElement = nextSibling; + } + } } if (mathElement) { protyle.toolbar.showRender(protyle, mathElement); return; } - fixTableRange(range); - if (!["DIV", "TD", "TH", "TR"].includes(range.startContainer.parentElement.tagName) && range.startOffset === 0 && !hasPreviousSibling(range.startContainer)) { - range.setStartBefore(range.startContainer.parentElement); - } - if (!["DIV", "TD", "TH", "TR"].includes(range.endContainer.parentElement.tagName) && range.endOffset === range.endContainer.textContent.length && !hasNextSibling(range.endContainer)) { - range.setEndAfter(range.endContainer.parentElement); - } - const wbrElement = document.createElement("wbr"); - range.insertNode(wbrElement); - const html = nodeElement.outerHTML; - - const newElement = document.createElement("span"); - const rangeString = range.toString(); - newElement.className = "render-node"; - newElement.setAttribute("contenteditable", "false"); - newElement.setAttribute("data-type", "inline-math"); - newElement.setAttribute("data-subtype", "math"); - newElement.setAttribute("data-content", rangeString.trim()); - range.extractContents(); - range.insertNode(newElement); - mathRender(newElement); - if (rangeString.trim() === "") { - protyle.toolbar.showRender(protyle, newElement, undefined, html); - } else { - range.setStartAfter(newElement); - range.collapse(true); - focusByRange(range); - nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); - updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, html); - wbrElement.remove(); - } + protyle.toolbar.setInlineMark(protyle, "inline-math", "range", { + type: "inline-math", + }); }); } } diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts index 81a9fa77d..19ddc66b3 100644 --- a/app/src/protyle/toolbar/index.ts +++ b/app/src/protyle/toolbar/index.ts @@ -42,6 +42,7 @@ import {previewTemplate} from "./util"; import {showMessage} from "../../dialog/message"; import {InlineMath} from "./InlineMath"; import {InlineMemo} from "./InlineMemo"; +import {mathRender} from "../markdown/mathRender"; export class Toolbar { public element: HTMLElement; @@ -379,6 +380,7 @@ export class Toolbar { rangeTypes.push(type); inlineElement.setAttribute("data-type", [...new Set(rangeTypes)].join(" ")); inlineElement.textContent = Constants.ZWSP; + setFontStyle(inlineElement, textObj); newNodes.push(inlineElement); } else { contents.childNodes.forEach((item: HTMLElement, index) => { @@ -486,7 +488,7 @@ export class Toolbar { newNodes.splice(i, 1); i--; } else { - this.range.insertNode(newNodes[i]); + this.range.insertNode(currentNewNode); this.range.collapse(false); } } @@ -499,12 +501,16 @@ export class Toolbar { if (previousIndex) { this.range.setStart(previousElement.firstChild, previousIndex); } else if (newNodes.length > 0) { - if (newNodes[0].firstChild) { - this.range.setStart(newNodes[0].firstChild, 0); - } else if (newNodes[0].nodeType === 3) { - this.range.setStart(newNodes[0], 0); + if (newNodes[0].nodeType !== 3 && (newNodes[0] as HTMLElement).getAttribute("data-type") === "inline-math") { + // 数学公式后面处理 } else { - this.range.setStartBefore(newNodes[0]); + if (newNodes[0].firstChild) { + this.range.setStart(newNodes[0].firstChild, 0); + } else if (newNodes[0].nodeType === 3) { + this.range.setStart(newNodes[0], 0); + } else { + this.range.setStartBefore(newNodes[0]); + } } } else if (nextElement) { // aaa**bbb** 选中 aaa 加粗 @@ -514,23 +520,39 @@ export class Toolbar { this.range.setEnd(nextElement.lastChild, nextIndex); } else if (newNodes.length > 0) { const lastNewNode = newNodes[newNodes.length - 1]; - if (lastNewNode.lastChild) { - this.range.setEnd(lastNewNode.lastChild, lastNewNode.lastChild.textContent.length); - } else if (lastNewNode.nodeType === 3) { - this.range.setEnd(lastNewNode, lastNewNode.textContent.length); - if (lastNewNode.textContent === Constants.ZWSP) { - // 粗体后取消粗体光标不存在 https://github.com/siyuan-note/insider/issues/1056 - this.range.collapse(false); + if (lastNewNode.nodeType !== 3 && (lastNewNode as HTMLElement).getAttribute("data-type") === "inline-math") { + if (lastNewNode.nextSibling) { + this.range.setStart(lastNewNode.nextSibling, 0); + } else { + this.range.setStartAfter(lastNewNode); } + this.range.collapse(true); } else { - // eg: 表格中有3行时,选中第二行三级,多次加粗会增加换行 - this.range.setEndAfter(lastNewNode); + if (lastNewNode.lastChild) { + this.range.setEnd(lastNewNode.lastChild, lastNewNode.lastChild.textContent.length); + } else if (lastNewNode.nodeType === 3) { + this.range.setEnd(lastNewNode, lastNewNode.textContent.length); + if (lastNewNode.textContent === Constants.ZWSP) { + // 粗体后取消粗体光标不存在 https://github.com/siyuan-note/insider/issues/1056 + this.range.collapse(false); + } + } else { + // eg: 表格中有3行时,选中第二行三级,多次加粗会增加换行 + this.range.setEndAfter(lastNewNode); + } } } else if (previousElement) { // **aaa**bbb 选中 bbb 加粗 // 需进行 mergeNode ,否用 alt+x 为相同颜色 aaabbb 中的 bbb 再次赋值后无法选中 this.range.setEnd(previousElement.firstChild, previousElement.firstChild.textContent.length); } + if (type === "inline-math") { + mathRender(nodeElement); + if (selectText === "") { + protyle.toolbar.showRender(protyle, newNodes[0] as HTMLElement, undefined, html); + return; + } + } nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss")); updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, html); const wbrElement = nodeElement.querySelector("wbr"); diff --git a/app/src/protyle/wysiwyg/getBlock.ts b/app/src/protyle/wysiwyg/getBlock.ts index a9d641e56..3a9039db1 100644 --- a/app/src/protyle/wysiwyg/getBlock.ts +++ b/app/src/protyle/wysiwyg/getBlock.ts @@ -152,7 +152,7 @@ export const getTopAloneElement = (topSourceElement: Element) => { export const hasNextSibling = (element: Node) => { let nextSibling = element.nextSibling; while (nextSibling) { - if (nextSibling.textContent === "") { + if (nextSibling.textContent === "" && nextSibling.nodeType === 3) { nextSibling = nextSibling.nextSibling; } else { return nextSibling; diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index ae44da9ce..31a8e9b60 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -683,8 +683,21 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { // https://github.com/siyuan-note/siyuan/issues/5547 const previousSibling = hasPreviousSibling(range.startContainer) as HTMLElement; if (range.startOffset === 1 && range.startContainer.textContent === Constants.ZWSP && - previousSibling && previousSibling.nodeType !== 3 && previousSibling.classList.contains("img")) { - previousSibling.classList.add("img--select"); + previousSibling && previousSibling.nodeType !== 3) { + if (previousSibling.classList.contains("img")) { + previousSibling.classList.add("img--select"); + } else if (previousSibling.getAttribute("data-type")?.indexOf("inline-math") > -1) { + // 数学公式相邻中有 zwsp,无法删除 + previousSibling.after(document.createElement("wbr")) + const oldHTML = nodeElement.outerHTML; + range.startContainer.textContent = ""; + previousSibling.remove(); + updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML); + focusByWbr(nodeElement, range); + event.stopPropagation(); + event.preventDefault(); + return; + } } const imgSelectElement = protyle.wysiwyg.element.querySelector(".img--select"); if (protyle.wysiwyg.element.querySelector(".protyle-wysiwyg--select")) { diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index e8c4f566f..eaf4bc282 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -31,7 +31,7 @@ interface Window { } interface ITextOption { - color: string, + color?: string, type: string }