diff --git a/app/src/protyle/render/av/action.ts b/app/src/protyle/render/av/action.ts
index 57d90458a..58c79b4c0 100644
--- a/app/src/protyle/render/av/action.ts
+++ b/app/src/protyle/render/av/action.ts
@@ -230,3 +230,25 @@ export const avContextmenu = (protyle: IProtyle, event: MouseEvent & { detail: a
});
return true;
};
+
+export const updateAVName = (protyle: IProtyle, blockElement: Element) => {
+ const avId = blockElement.getAttribute("data-av-id");
+ const nameElement = blockElement.querySelector(".av__title") as HTMLElement;
+ if (nameElement.textContent.trim() === nameElement.dataset.title.trim()) {
+ return;
+ }
+ transaction(protyle, [{
+ action: "setAttrView",
+ id: avId,
+ data: {
+ name: nameElement.textContent.trim(),
+ }
+ }], [{
+ action: "setAttrView",
+ id: avId,
+ data: {
+ name: nameElement.dataset.title,
+ }
+ }])
+ nameElement.dataset.title = nameElement.textContent.trim();
+}
diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts
index 7868bf213..89c56f243 100644
--- a/app/src/protyle/render/av/render.ts
+++ b/app/src/protyle/render/av/render.ts
@@ -105,7 +105,7 @@ ${cell.color ? `color:${cell.color};` : ""}">${text}<
- ${data.name || ""}
+ ${data.name || ""}
@@ -137,7 +137,7 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
}
lastElement = protyle.contentElement;
lastParentID = operation.parentID;
- const avId = operation.action === "setAttrView"?operation.id: operation.parentID
+ const avId = operation.action === "setAttrView" ? operation.id : operation.parentID
if (operation.action === "addAttrViewCol") {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
item.removeAttribute("data-render");
@@ -156,6 +156,15 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => {
(rowItem.querySelector(`[data-index="${index}"]`) as HTMLElement).style.width = operation.data;
});
});
+ } else if (operation.action === "setAttrView" && typeof operation.data.name === "string") {
+ Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
+ const titleElement = item.querySelector(".av__title") as HTMLElement;
+ if (!titleElement || titleElement.textContent.trim() === operation.data.name) {
+ return;
+ }
+ titleElement.textContent = operation.data.name;
+ titleElement.dataset.title = operation.data.name;
+ });
} else {
Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-av-id="${avId}"]`)).forEach((item: HTMLElement) => {
item.removeAttribute("data-render");
diff --git a/app/src/protyle/toolbar/index.ts b/app/src/protyle/toolbar/index.ts
index 1af5949f3..d31c63179 100644
--- a/app/src/protyle/toolbar/index.ts
+++ b/app/src/protyle/toolbar/index.ts
@@ -75,7 +75,7 @@ export class Toolbar {
public render(protyle: IProtyle, range: Range, event?: KeyboardEvent) {
this.range = range;
let nodeElement = hasClosestBlock(range.startContainer);
- if (isMobile() || !nodeElement || protyle.disabled) {
+ if (isMobile() || !nodeElement || protyle.disabled || nodeElement.classList.contains("av")) {
this.element.classList.add("fn__none");
return;
}
diff --git a/app/src/protyle/util/insertHTML.ts b/app/src/protyle/util/insertHTML.ts
index bee1251b3..da32330f9 100644
--- a/app/src/protyle/util/insertHTML.ts
+++ b/app/src/protyle/util/insertHTML.ts
@@ -7,6 +7,8 @@ import {mathRender} from "../render/mathRender";
import {Constants} from "../../constants";
import {highlightRender} from "../render/highlightRender";
import {scrollCenter} from "../../util/highlightById";
+import {updateAVName} from "../render/av/action";
+import {readText} from "./compatibility";
export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
// 移动端插入嵌入块时,获取到的 range 为旧值
@@ -31,6 +33,22 @@ export const insertHTML = (html: string, protyle: IProtyle, isBlock = false,
if (!blockElement) {
return;
}
+ if (blockElement.classList.contains("av")) {
+ range.deleteContents();
+ const text = readText();
+ if (typeof text === "string") {
+ range.insertNode(document.createTextNode(text));
+ range.collapse(false);
+ updateAVName(protyle, blockElement);
+ } else {
+ text.then((t) => {
+ range.insertNode(document.createTextNode(t));
+ range.collapse(false);
+ updateAVName(protyle, blockElement);
+ });
+ }
+ return;
+ }
let id = blockElement.getAttribute("data-node-id");
range.insertNode(document.createElement("wbr"));
let oldHTML = blockElement.outerHTML;
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 3e8c13190..fb1b20fe0 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -75,7 +75,7 @@ import {getBacklinkHeadingMore, loadBreadcrumb} from "./renderBacklink";
import {removeSearchMark} from "../toolbar/util";
import {activeBlur, hideKeyboardToolbar} from "../../mobile/util/keyboardToolbar";
import {commonClick} from "./commonClick";
-import {avClick, avContextmenu} from "../render/av/action";
+import {avClick, avContextmenu, updateAVName} from "../render/av/action";
export class WYSIWYG {
public lastHTMLs: { [key: string]: string } = {};
@@ -1037,8 +1037,6 @@ export class WYSIWYG {
event.stopPropagation();
return;
}
- event.stopPropagation();
- event.preventDefault();
if (protyle.options.render.breadcrumb) {
protyle.breadcrumb.hide();
@@ -1046,8 +1044,18 @@ export class WYSIWYG {
const range = getEditorRange(protyle.wysiwyg.element);
let nodeElement = hasClosestBlock(range.startContainer);
if (!nodeElement) {
+ event.stopPropagation();
+ event.preventDefault();
return;
}
+ if (nodeElement.classList.contains("av")) {
+ updateAVName(protyle, nodeElement);
+ event.stopPropagation();
+ return;
+ }
+
+ event.stopPropagation();
+ event.preventDefault();
const selectImgElement = nodeElement.querySelector(".img--select");
let selectElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select"));
if (selectElements.length === 0 && range.toString() === "" && !range.cloneContents().querySelector("img") &&
@@ -1309,7 +1317,7 @@ export class WYSIWYG {
if (!isNotEditBlock(nodeElement) && !nodeElement.classList.contains("protyle-wysiwyg--select") &&
(isMobile() || event.detail.target || (beforeContextmenuRange && nodeElement.contains(beforeContextmenuRange.startContainer)))
) {
- if (!isMobile() || protyle.toolbar?.element.classList.contains("fn__none")) {
+ if ((!isMobile() || protyle.toolbar?.element.classList.contains("fn__none")) && !nodeElement.classList.contains("av")) {
contentMenu(protyle, nodeElement);
window.siyuan.menus.menu.popup({x, y: y + 13, h: 26});
protyle.toolbar?.element.classList.add("fn__none");
@@ -1438,9 +1446,6 @@ export class WYSIWYG {
});
this.element.addEventListener("compositionend", (event: InputEvent) => {
- if ((event.target as HTMLElement).classList.contains("av__title")) {
- return;
- }
event.stopPropagation();
isComposition = false;
const range = getEditorRange(this.element);
@@ -1467,8 +1472,7 @@ export class WYSIWYG {
this.element.addEventListener("input", (event: InputEvent) => {
const target = event.target as HTMLElement;
- if (target.tagName === "VIDEO" || target.tagName === "AUDIO" || event.inputType === "historyRedo" ||
- target.classList.contains("av__title")) {
+ if (target.tagName === "VIDEO" || target.tagName === "AUDIO" || event.inputType === "historyRedo") {
return;
}
if (event.inputType === "historyUndo") {
diff --git a/app/src/protyle/wysiwyg/input.ts b/app/src/protyle/wysiwyg/input.ts
index f5bc46b9d..533805ea2 100644
--- a/app/src/protyle/wysiwyg/input.ts
+++ b/app/src/protyle/wysiwyg/input.ts
@@ -12,12 +12,17 @@ import {hideElements} from "../ui/hideElements";
import {hasClosestByAttribute} from "../util/hasClosest";
import {fetchPost, fetchSyncPost} from "../../util/fetch";
import {headingTurnIntoList, turnIntoTaskList} from "./turnIntoList";
+import {updateAVName} from "../render/av/action";
export const input = async (protyle: IProtyle, blockElement: HTMLElement, range: Range, needRender = true) => {
if (!blockElement.parentElement) {
// 不同 windows 版本下输入法会多次触发 input,导致 outerhtml 赋值的块丢失
return;
}
+ if (blockElement.classList.contains("av")) {
+ updateAVName(protyle, blockElement);
+ return;
+ }
const editElement = getContenteditableElement(blockElement) as HTMLElement;
const type = blockElement.getAttribute("data-type");
if (!editElement) {
diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts
index bbe198b34..3ca8295dd 100644
--- a/app/src/protyle/wysiwyg/keydown.ts
+++ b/app/src/protyle/wysiwyg/keydown.ts
@@ -97,6 +97,12 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
if (!nodeElement) {
return;
}
+ if (nodeElement.classList.contains("av")) {
+ if (matchHotKey("⌘B", event) || matchHotKey("⌘I", event) || matchHotKey("⌘U", event)) {
+ event.preventDefault();
+ }
+ return;
+ }
if (nodeElement.classList.contains("protyle-wysiwyg--select") && !isCtrl(event) && !event.shiftKey && !event.altKey) {
if (event.key.toLowerCase() === "a") {
event.stopPropagation();