diff --git a/app/src/assets/scss/_wysiwyg.scss b/app/src/assets/scss/_wysiwyg.scss index b284e2ef6..151da52a3 100644 --- a/app/src/assets/scss/_wysiwyg.scss +++ b/app/src/assets/scss/_wysiwyg.scss @@ -239,8 +239,8 @@ background-color: var(--b3-protyle-inline-mark-background); } - span[data-type="block-ref"], - span[data-type="file-annotation-ref"] { + span[data-type~="block-ref"], + span[data-type~="file-annotation-ref"] { color: var(--b3-protyle-inline-blockref-color); opacity: .86; transition: var(--b3-transition); @@ -573,10 +573,10 @@ // 导出 html 不需要编辑样式 .protyle-wysiwyg[contenteditable="true"] { - span[data-type="inline-math"], - span[data-type="tag"], - span[data-type="block-ref"], - span[data-type="file-annotation-ref"], + span[data-type~="inline-math"], + span[data-type~="tag"], + span[data-type~="block-ref"], + span[data-type~="file-annotation-ref"], .protyle-action__language, .img > span:nth-child(2), .li > .protyle-action, @@ -584,12 +584,12 @@ cursor: pointer; } - span[data-type="tag"]:hover { + span[data-type~="tag"]:hover { background-color: var(--b3-border-color); } - span[data-type="block-ref"]:hover, - span[data-type="file-annotation-ref"]:hover { + span[data-type~="block-ref"]:hover, + span[data-type~="file-annotation-ref"]:hover { opacity: 1; } diff --git a/app/src/block/popover.ts b/app/src/block/popover.ts index 6d477d03f..cf225d033 100644 --- a/app/src/block/popover.ts +++ b/app/src/block/popover.ts @@ -132,7 +132,7 @@ export const initBlockPopover = () => { ids = [dataId]; } defIds = JSON.parse(popoverTargetElement.getAttribute("data-defids") || "[]"); - } else if (popoverTargetElement.getAttribute("data-type") === "virtual-block-ref") { + } else if (popoverTargetElement.getAttribute("data-type").indexOf("virtual-block-ref") > -1) { const nodeElement = hasClosestBlock(popoverTargetElement); if (nodeElement) { const postResponse = await fetchSyncPost("/api/block/getBlockDefIDsByRefText", { diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index a5a4b1010..28218bd47 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -794,7 +794,10 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText icon: "iconGraph", click() { linkElement.setAttribute("data-subtype", "s"); - linkElement.setAttribute("data-type", "block-ref"); + const types = linkElement.getAttribute("data-type").split(" "); + 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.removeAttribute("data-href"); linkElement.removeAttribute("data-title"); diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index aebb849a9..cb7186965 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -322,7 +322,7 @@ export class Gutter { updateTransaction(options.protyle, options.id, newHTML, oldHTML); } focusByWbr(options.protyle.wysiwyg.element, getEditorRange(options.protyle.wysiwyg.element)); - options.protyle.wysiwyg.element.querySelectorAll('[data-type="block-ref"]').forEach(item => { + options.protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => { if (item.textContent === "") { fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => { item.innerHTML = response.data; diff --git a/app/src/protyle/hint/index.ts b/app/src/protyle/hint/index.ts index 0dbb5894a..a14f329d5 100644 --- a/app/src/protyle/hint/index.ts +++ b/app/src/protyle/hint/index.ts @@ -439,9 +439,9 @@ ${unicode2Emoji(emoji.unicode, true)}`; } return; } - range.deleteContents(); range.insertNode(document.createElement("wbr")); html = nodeElement.outerHTML; + range.deleteContents(); const tempElement = document.createElement("template"); tempElement.innerHTML = value.replace(//g, "").replace(/<\/mark>/g, ""); range.insertNode(tempElement.content.cloneNode(true)); diff --git a/app/src/protyle/index.ts b/app/src/protyle/index.ts index d9b460772..99bb31bdf 100644 --- a/app/src/protyle/index.ts +++ b/app/src/protyle/index.ts @@ -129,7 +129,7 @@ class Protyle { } } // update ref - this.protyle.wysiwyg.element.querySelectorAll(`[data-type="block-ref"][data-id="${data.data.id}"]`).forEach(item => { + this.protyle.wysiwyg.element.querySelectorAll(`[data-type="~block-ref"][data-id="${data.data.id}"]`).forEach(item => { if (item.getAttribute("data-subtype") === "d") { item.textContent = data.data.title; } diff --git a/app/src/protyle/toolbar/BlockRef.ts b/app/src/protyle/toolbar/BlockRef.ts index 086ccdad6..b7f86f47e 100644 --- a/app/src/protyle/toolbar/BlockRef.ts +++ b/app/src/protyle/toolbar/BlockRef.ts @@ -1,4 +1,5 @@ import {ToolbarItem} from "./ToolbarItem"; +import {hintRef} from "../hint/extend"; export class BlockRef extends ToolbarItem { public element: HTMLElement; @@ -7,7 +8,7 @@ export class BlockRef extends ToolbarItem { super(protyle, menuItem); // 不能用 getEventName,否则会导致光标位置变动到点击的文档中 this.element.addEventListener("click", (event: MouseEvent & { changedTouches: MouseEvent[] }) => { - protyle.toolbar.setInlineMark(protyle, "blockRef", "add"); + hintRef(protyle.toolbar.range.toString(), protyle, true); protyle.toolbar.element.classList.add("fn__none"); event.stopPropagation(); }); diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts index 6afa1a3e7..29d0251d5 100644 --- a/app/src/protyle/toolbar/index.ts +++ b/app/src/protyle/toolbar/index.ts @@ -126,7 +126,7 @@ export class Toolbar { }); const types = this.getCurrentType(); types.forEach(item => { - if (item === "blockRef") { + if (item === "block-ref" || item === "text") { return; } this.element.querySelector(`[data-type="${item}"]`).classList.add("protyle-toolbar__item--current"); @@ -600,15 +600,15 @@ export class Toolbar { newElement = document.createElement("span"); newElement.setAttribute("data-type", "a"); break; - case "blockRef": - if (refText === "") { - wbrElement.remove(); - return; - } - this.range.insertNode(refNode); - this.range.selectNodeContents(refNode); - hintRef(refText, protyle, true); - break; + // case "blockRef": + // if (refText === "") { + // wbrElement.remove(); + // return; + // } + // this.range.insertNode(refNode); + // this.range.selectNodeContents(refNode); + // hintRef(refText, protyle, true); + // break; case "inline-math": newElement = document.createElement("span"); newElement.className = "render-node"; diff --git a/app/src/protyle/util/hasClosest.ts b/app/src/protyle/util/hasClosest.ts index 941ff1337..a650eebb9 100644 --- a/app/src/protyle/util/hasClosest.ts +++ b/app/src/protyle/util/hasClosest.ts @@ -72,7 +72,7 @@ export const hasClosestByAttribute = (element: Node, attr: string, value: string let e = element as HTMLElement; let isClosest = false; while (e && !isClosest && (top ? e.tagName !== "BODY" : !e.classList.contains("protyle-wysiwyg"))) { - if (typeof value === "string" && e.getAttribute(attr) === value) { + if (typeof value === "string" && e.getAttribute(attr)?.split(" ").includes(value)) { isClosest = true; } else if (typeof value !== "string" && e.hasAttribute(attr)) { isClosest = true; diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts index 7175e1482..e519633f9 100644 --- a/app/src/protyle/util/insertHTML.ts +++ b/app/src/protyle/util/insertHTML.ts @@ -54,9 +54,11 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false) => if (inlineMathElement) { // 表格内选中数学公式 https://ld246.com/article/1631708573504 inlineMathElement.remove(); - } else if (range.startContainer.nodeType === 3 && range.startContainer.parentElement.getAttribute("data-type") === "block-ref") { + } else if (range.startContainer.nodeType === 3 && range.startContainer.parentElement.getAttribute("data-type").indexOf("block-ref")>-1) { // ref 选中处理 https://ld246.com/article/1629214377537 range.startContainer.parentElement.remove(); + // 选中 ref**bbb** 后 alt+[ + range.deleteContents(); } else { range.deleteContents(); } diff --git a/app/src/protyle/util/paste.ts b/app/src/protyle/util/paste.ts index 4ec6e400a..2b37b43d8 100644 --- a/app/src/protyle/util/paste.ts +++ b/app/src/protyle/util/paste.ts @@ -246,7 +246,7 @@ export const paste = async (protyle: IProtyle, event: (ClipboardEvent | DragEven dom: tempElement.innerHTML }, (response) => { insertHTML(response.data, protyle); - protyle.wysiwyg.element.querySelectorAll('[data-type="block-ref"]').forEach(item => { + protyle.wysiwyg.element.querySelectorAll('[data-type~="block-ref"]').forEach(item => { if (item.textContent === "") { fetchPost("/api/block/getRefText", {id: item.getAttribute("data-id")}, (response) => { item.innerHTML = response.data; diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 5477bc5eb..3e9636d55 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -1068,8 +1068,8 @@ export class WYSIWYG { return false; } protyle.toolbar.range = getEditorRange(protyle.element); - const type = target.getAttribute("data-type"); - if (type === "block-ref") { + const types = target.getAttribute("data-type").split(" "); + if (types.includes("block-ref")) { refMenu(protyle, target); // 阻止 popover target.setAttribute("prevent-popover", "true"); @@ -1078,11 +1078,11 @@ export class WYSIWYG { }, 620); return false; } - if (type === "file-annotation-ref") { + if (types.includes("file-annotation-ref")) { protyle.toolbar.showFileAnnotationRef(protyle, target); return false; } - if (type === "a") { + if (types.includes("a")) { linkMenu(protyle, target); if (target.getAttribute("data-href")?.startsWith("siyuan://blocks")) { // 阻止 popover diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index a8ba6549d..f6d6ef8cc 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -413,7 +413,7 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { const ids = protyle.path.split("/"); if (ids.length > 2) { /// #if MOBILE - openMobileFileById(ids[ids.length - 2],[Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]); + openMobileFileById(ids[ids.length - 2], [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]); /// #else openFileById({ id: ids[ids.length - 2], @@ -520,14 +520,14 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { event.preventDefault(); const inlineElement = hasClosestByAttribute(range.startContainer, "data-type", null); if (inlineElement) { - const type = inlineElement.getAttribute("data-type"); - if (type === "block-ref") { + const types = inlineElement.getAttribute("data-type").split(" "); + if (types.includes("block-ref")) { refMenu(protyle, inlineElement); return; - } else if (type === "file-annotation-ref") { + } else if (types.includes("file-annotation-ref")) { protyle.toolbar.showFileAnnotationRef(protyle, inlineElement); return; - } else if (type === "a") { + } else if (types.includes("a")) { linkMenu(protyle, inlineElement); return; } @@ -1185,8 +1185,8 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { } if (matchHotKey(menuItem.hotkey, event)) { protyle.toolbar.range = getEditorRange(protyle.wysiwyg.element); - if (menuItem.name === "text") { - protyle.toolbar.element.querySelector('[data-type="text"]').dispatchEvent(new CustomEvent(getEventName())); + if (menuItem.name === "text" || menuItem.name === "block-ref") { + protyle.toolbar.element.querySelector(`[data-type="${menuItem.name}"]`).dispatchEvent(new CustomEvent(getEventName())); } else { protyle.toolbar.setInlineMark(protyle, menuItem.name, "range"); } diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 8927db952..8629ba180 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -132,7 +132,7 @@ const promiseTransaction = () => { } }); // 更新引用块 - protyle.wysiwyg.element.querySelectorAll(`[data-type="block-ref"][data-id="${operation.id}"]`).forEach(item => { + protyle.wysiwyg.element.querySelectorAll(`[data-type~="block-ref"][data-id="${operation.id}"]`).forEach(item => { if (item.getAttribute("data-subtype") === "d") { item.textContent = "block not found"; } @@ -265,7 +265,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b } }); // 更新 ws 引用块 - protyle.wysiwyg.element.querySelectorAll(`[data-type="block-ref"][data-id="${operation.id}"]`).forEach(item => { + protyle.wysiwyg.element.querySelectorAll(`[data-type~="block-ref"][data-id="${operation.id}"]`).forEach(item => { if (item.getAttribute("data-subtype") === "d") { item.textContent = "block not found"; } @@ -701,7 +701,7 @@ const updateRef = (protyle: IProtyle, id: string, index = 0) => { if (index > 6) { return; } - protyle.wysiwyg.element.querySelectorAll(`[data-type="block-ref"][data-id="${id}"]`).forEach(item => { + protyle.wysiwyg.element.querySelectorAll(`[data-type~="block-ref"][data-id="${id}"]`).forEach(item => { if (item.getAttribute("data-subtype") === "d") { fetchPost("/api/block/getRefText", {id: id}, (response) => { item.innerHTML = response.data;