A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {ToolbarItem} from "./ToolbarItem";
2import {hasClosestBlock, hasClosestByAttribute} from "../util/hasClosest";
3import {hasNextSibling, hasPreviousSibling} from "../wysiwyg/getBlock";
4
5export class InlineMath extends ToolbarItem {
6 public element: HTMLElement;
7
8 constructor(protyle: IProtyle, menuItem: IMenuItem) {
9 super(protyle, menuItem);
10 this.element.addEventListener("click", async (event: MouseEvent & { changedTouches: MouseEvent[] }) => {
11 protyle.toolbar.element.classList.add("fn__none");
12 event.stopPropagation();
13
14 const range = protyle.toolbar.range;
15 const nodeElement = hasClosestBlock(range.startContainer);
16 if (!nodeElement) {
17 return;
18 }
19 let mathElement = hasClosestByAttribute(range.startContainer, "data-type", "inline-math") as Element;
20 if (!mathElement && range.startContainer.nodeType !== 3 && range.startContainer.childNodes[range.startOffset]) {
21 const previousSibling = hasPreviousSibling(range.startContainer.childNodes[range.startOffset]) as HTMLElement;
22 if (previousSibling && previousSibling.nodeType !==3 && previousSibling.getAttribute("data-type").indexOf("inline-math") > -1) {
23 mathElement = previousSibling;
24 }
25 }
26 if (!mathElement && range.startOffset === range.startContainer.textContent.length && range.startContainer.nodeType === 3) {
27 let isMath = true;
28 let hasMath = false;
29 // https://github.com/siyuan-note/siyuan/issues/6007
30 range.cloneContents().childNodes.forEach((item: HTMLElement) => {
31 if ((item.nodeType !== 3 && (item.getAttribute("data-type") || "").indexOf("inline-math") > -1) ||
32 (item.nodeType == 3 && item.textContent === "")) {
33 // 是否仅选中数学公式
34 hasMath = true;
35 } else {
36 isMath = false;
37 }
38 });
39 if (isMath && hasMath) {
40 const nextSibling = hasNextSibling(range.startContainer) as HTMLElement;
41 if (nextSibling && nextSibling.nodeType !== 3 && nextSibling.getAttribute("data-type").indexOf("inline-math") > -1) {
42 mathElement = nextSibling;
43 } else {
44 const previousSibling = hasPreviousSibling(range.startContainer) as HTMLElement;
45 if (range.startOffset === 0 && previousSibling && previousSibling.nodeType !== 3 && previousSibling.getAttribute("data-type").indexOf("inline-math") > -1) {
46 mathElement = previousSibling;
47 }
48 }
49 }
50 }
51 if (mathElement) {
52 protyle.toolbar.showRender(protyle, mathElement);
53 return;
54 }
55 protyle.toolbar.setInlineMark(protyle, "inline-math", "range", {
56 type: "inline-math",
57 });
58 });
59 }
60}