diff --git a/app/src/layout/dock/Tag.ts b/app/src/layout/dock/Tag.ts
index a8c486cc6..fa9e67917 100644
--- a/app/src/layout/dock/Tag.ts
+++ b/app/src/layout/dock/Tag.ts
@@ -6,9 +6,9 @@ import {fetchPost} from "../../util/fetch";
import {updateHotkeyTip} from "../../protyle/util/compatibility";
import {openGlobalSearch} from "../../search/util";
import {MenuItem} from "../../menus/Menu";
-import {Dialog} from "../../dialog";
import {confirmDialog} from "../../dialog/confirmDialog";
import {escapeHtml} from "../../util/escape";
+import {renameTag} from "./util";
export class Tag extends Model {
private openNodes: string[];
@@ -86,28 +86,7 @@ export class Tag extends Model {
window.siyuan.menus.menu.append(new MenuItem({
label: window.siyuan.languages.rename,
click() {
- const dialog = new Dialog({
- title: window.siyuan.languages.rename,
- content: `
-
-
-
-
`,
- width: "520px",
- });
- const btnsElement = dialog.element.querySelectorAll(".b3-button");
- btnsElement[0].addEventListener("click", () => {
- dialog.destroy();
- });
- const inputElement = dialog.element.querySelector("input");
- dialog.bindInput(inputElement, () => {
- (btnsElement[1] as HTMLButtonElement).click();
- });
- inputElement.focus();
- inputElement.select();
- btnsElement[1].addEventListener("click", () => {
- fetchPost("/api/tag/renameTag", {oldLabel: labelName, newLabel: inputElement.value});
- });
+ renameTag(labelName);
}
}).element);
window.siyuan.menus.menu.append(new MenuItem({
diff --git a/app/src/layout/dock/util.ts b/app/src/layout/dock/util.ts
index 5e2e2e937..d4ac60b80 100644
--- a/app/src/layout/dock/util.ts
+++ b/app/src/layout/dock/util.ts
@@ -4,6 +4,8 @@ import {Graph} from "./Graph";
import {Outline} from "./Outline";
import {switchWnd} from "../util";
import {Backlink} from "./Backlink";
+import {Dialog} from "../../dialog";
+import {fetchPost} from "../../util/fetch";
export const openBacklink = (protyle: IProtyle) => {
const backlink = getAllModels().backlink.find(item => {
@@ -85,3 +87,28 @@ export const openOutline = (protyle: IProtyle) => {
newWnd.element.style.width = "200px";
switchWnd(newWnd, protyle.model.parent.parent);
};
+
+export const renameTag = (labelName: string) => {
+ const dialog = new Dialog({
+ title: window.siyuan.languages.rename,
+ content: `
+
+
+
+
`,
+ width: "520px",
+ });
+ const btnsElement = dialog.element.querySelectorAll(".b3-button");
+ btnsElement[0].addEventListener("click", () => {
+ dialog.destroy();
+ });
+ const inputElement = dialog.element.querySelector("input");
+ dialog.bindInput(inputElement, () => {
+ (btnsElement[1] as HTMLButtonElement).click();
+ });
+ inputElement.focus();
+ inputElement.select();
+ btnsElement[1].addEventListener("click", () => {
+ fetchPost("/api/tag/renameTag", {oldLabel: labelName, newLabel: inputElement.value});
+ });
+}
diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts
index 261ea812e..ed53c4b5e 100644
--- a/app/src/menus/protyle.ts
+++ b/app/src/menus/protyle.ts
@@ -46,6 +46,8 @@ import {removeLink} from "../protyle/toolbar/Link";
import {alignImgCenter, alignImgLeft} from "../protyle/wysiwyg/commonHotkey";
import {getEnableHTML} from "../protyle/wysiwyg/removeEmbed";
import {updateTitle} from "../dialog/processSystem";
+import {renameTag} from "../layout/dock/util";
+import {openGlobalSearch} from "../search/util";
export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
const nodeElement = hasClosestBlock(element);
@@ -897,6 +899,99 @@ export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText
}
};
+export const tagMenu = (protyle: IProtyle, tagElement: HTMLElement) => {
+ window.siyuan.menus.menu.remove();
+ const nodeElement = hasClosestBlock(tagElement);
+ if (!nodeElement) {
+ return;
+ }
+ const id = nodeElement.getAttribute("data-node-id");
+ let html = nodeElement.outerHTML;
+ window.siyuan.menus.menu.append(new MenuItem({
+ label: ``,
+ bind(element) {
+ const inputElement = element.querySelector("input");
+ inputElement.value = tagElement.textContent.replace(Constants.ZWSP, "");
+ inputElement.addEventListener("change", () => {
+ updateTransaction(protyle, id, nodeElement.outerHTML, html);
+ html = nodeElement.outerHTML;
+ });
+ inputElement.addEventListener("compositionend", () => {
+ tagElement.innerHTML = Constants.ZWSP + Lute.EscapeHTMLStr(inputElement.value || "");
+ });
+ inputElement.addEventListener("input", (event: KeyboardEvent) => {
+ if (!event.isComposing) {
+ // https://github.com/siyuan-note/siyuan/issues/4511
+ tagElement.innerHTML = Constants.ZWSP + Lute.EscapeHTMLStr(inputElement.value || "");
+ }
+ });
+ inputElement.addEventListener("keydown", (event) => {
+ if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!inputElement.value) {
+ const oldHTML = nodeElement.outerHTML;
+ tagElement.insertAdjacentHTML("afterend", "");
+ tagElement.remove();
+ nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
+ updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
+ focusByWbr(nodeElement, protyle.toolbar.range);
+ } else {
+ protyle.toolbar.range.selectNodeContents(tagElement);
+ protyle.toolbar.range.collapse(false);
+ focusByRange(protyle.toolbar.range);
+ }
+ window.siyuan.menus.menu.remove();
+ } else if (electronUndo(event)) {
+ return;
+ }
+ });
+ }
+ }).element);
+ window.siyuan.menus.menu.append(new MenuItem({
+ label: window.siyuan.languages.search,
+ accelerator: "Click",
+ icon: "iconSearch",
+ click() {
+ openGlobalSearch(`#${tagElement.textContent}#`, false);
+ }
+ }).element);
+ window.siyuan.menus.menu.append(new MenuItem({
+ label: `${window.siyuan.languages.turnInto} ${window.siyuan.languages.text}`,
+ icon: "iconRefresh",
+ click() {
+ protyle.toolbar.range.setStart(tagElement.firstChild, 0);
+ protyle.toolbar.range.setEnd(tagElement.lastChild, tagElement.lastChild.textContent.length);
+ protyle.toolbar.setInlineMark(protyle, "tag", "range");
+ }
+ }).element);
+ window.siyuan.menus.menu.append(new MenuItem({
+ label: window.siyuan.languages.rename,
+ click() {
+ renameTag(tagElement.textContent.replace(Constants.ZWSP, ""))
+ }
+ }).element);
+ window.siyuan.menus.menu.append(new MenuItem({
+ icon: "iconTrashcan",
+ label: window.siyuan.languages.remove,
+ click() {
+ const oldHTML = nodeElement.outerHTML;
+ tagElement.insertAdjacentHTML("afterend", "");
+ tagElement.remove();
+ nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
+ updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
+ focusByWbr(nodeElement, protyle.toolbar.range);
+ }
+ }).element);
+ const rect = tagElement.getBoundingClientRect();
+ window.siyuan.menus.menu.popup({
+ x: rect.left,
+ y: rect.top + 26,
+ h: 26
+ });
+ window.siyuan.menus.menu.element.querySelector("input").select();
+};
+
const genImageWidthMenu = (label: string, assetElement: HTMLElement, imgElement: HTMLElement, protyle: IProtyle, id: string, nodeElement: HTMLElement, html: string) => {
return {
label,
diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts
index 92b76e884..c52f92693 100644
--- a/app/src/protyle/wysiwyg/index.ts
+++ b/app/src/protyle/wysiwyg/index.ts
@@ -19,7 +19,7 @@ import {getSearch, isMobile} from "../../util/functions";
import {isLocalPath, pathPosix} from "../../util/pathName";
import {genEmptyElement} from "../../block/util";
import {previewImage} from "../preview/image";
-import {contentMenu, imgMenu, linkMenu, refMenu, setFold, zoomOut} from "../../menus/protyle";
+import {contentMenu, imgMenu, linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
import * as dayjs from "dayjs";
import {dropEvent} from "../util/editorCommonEvent";
import {input} from "./input";
@@ -1158,13 +1158,18 @@ export class WYSIWYG {
protyle.toolbar.showFileAnnotationRef(protyle, target);
return false;
}
+ if (types.includes("tag")) {
+ tagMenu(protyle, target);
+ return false;
+ }
if (types.includes("inline-memo")) {
protyle.toolbar.showRender(protyle, target);
return false;
}
if (types.includes("a")) {
linkMenu(protyle, target);
- if (target.getAttribute("data-href")?.startsWith("siyuan://blocks")) {
+ if (window.siyuan.config.editor.floatWindowMode === 0 &&
+ target.getAttribute("data-href")?.startsWith("siyuan://blocks")) {
// 阻止 popover
target.setAttribute("prevent-popover", "true");
setTimeout(() => {
diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts
index 74277abb9..4acc32692 100644
--- a/app/src/protyle/wysiwyg/keydown.ts
+++ b/app/src/protyle/wysiwyg/keydown.ts
@@ -52,7 +52,7 @@ import {
goHome,
upSelect
} from "./commonHotkey";
-import {linkMenu, refMenu, setFold, zoomOut} from "../../menus/protyle";
+import {linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
import {removeEmbed} from "./removeEmbed";
import {openAttr} from "../../menus/commonMenuItem";
import {Constants} from "../../constants";
@@ -534,6 +534,9 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
} else if (types.includes("a")) {
linkMenu(protyle, inlineElement);
return;
+ } else if (types.includes("tag")) {
+ tagMenu(protyle, inlineElement);
+ return;
}
}