mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-22 09:30:14 +01:00
This commit is contained in:
parent
4db1dc065a
commit
46b818c987
5 changed files with 135 additions and 26 deletions
|
|
@ -6,9 +6,9 @@ import {fetchPost} from "../../util/fetch";
|
||||||
import {updateHotkeyTip} from "../../protyle/util/compatibility";
|
import {updateHotkeyTip} from "../../protyle/util/compatibility";
|
||||||
import {openGlobalSearch} from "../../search/util";
|
import {openGlobalSearch} from "../../search/util";
|
||||||
import {MenuItem} from "../../menus/Menu";
|
import {MenuItem} from "../../menus/Menu";
|
||||||
import {Dialog} from "../../dialog";
|
|
||||||
import {confirmDialog} from "../../dialog/confirmDialog";
|
import {confirmDialog} from "../../dialog/confirmDialog";
|
||||||
import {escapeHtml} from "../../util/escape";
|
import {escapeHtml} from "../../util/escape";
|
||||||
|
import {renameTag} from "./util";
|
||||||
|
|
||||||
export class Tag extends Model {
|
export class Tag extends Model {
|
||||||
private openNodes: string[];
|
private openNodes: string[];
|
||||||
|
|
@ -86,28 +86,7 @@ export class Tag extends Model {
|
||||||
window.siyuan.menus.menu.append(new MenuItem({
|
window.siyuan.menus.menu.append(new MenuItem({
|
||||||
label: window.siyuan.languages.rename,
|
label: window.siyuan.languages.rename,
|
||||||
click() {
|
click() {
|
||||||
const dialog = new Dialog({
|
renameTag(labelName);
|
||||||
title: window.siyuan.languages.rename,
|
|
||||||
content: `<div class="b3-dialog__content"><input class="b3-text-field fn__block" value="${labelName}"></div>
|
|
||||||
<div class="b3-dialog__action">
|
|
||||||
<button class="b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button><div class="fn__space"></div>
|
|
||||||
<button class="b3-button b3-button--text">${window.siyuan.languages.confirm}</button>
|
|
||||||
</div>`,
|
|
||||||
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});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).element);
|
}).element);
|
||||||
window.siyuan.menus.menu.append(new MenuItem({
|
window.siyuan.menus.menu.append(new MenuItem({
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import {Graph} from "./Graph";
|
||||||
import {Outline} from "./Outline";
|
import {Outline} from "./Outline";
|
||||||
import {switchWnd} from "../util";
|
import {switchWnd} from "../util";
|
||||||
import {Backlink} from "./Backlink";
|
import {Backlink} from "./Backlink";
|
||||||
|
import {Dialog} from "../../dialog";
|
||||||
|
import {fetchPost} from "../../util/fetch";
|
||||||
|
|
||||||
export const openBacklink = (protyle: IProtyle) => {
|
export const openBacklink = (protyle: IProtyle) => {
|
||||||
const backlink = getAllModels().backlink.find(item => {
|
const backlink = getAllModels().backlink.find(item => {
|
||||||
|
|
@ -85,3 +87,28 @@ export const openOutline = (protyle: IProtyle) => {
|
||||||
newWnd.element.style.width = "200px";
|
newWnd.element.style.width = "200px";
|
||||||
switchWnd(newWnd, protyle.model.parent.parent);
|
switchWnd(newWnd, protyle.model.parent.parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const renameTag = (labelName: string) => {
|
||||||
|
const dialog = new Dialog({
|
||||||
|
title: window.siyuan.languages.rename,
|
||||||
|
content: `<div class="b3-dialog__content"><input class="b3-text-field fn__block" value="${labelName}"></div>
|
||||||
|
<div class="b3-dialog__action">
|
||||||
|
<button class="b3-button b3-button--cancel">${window.siyuan.languages.cancel}</button><div class="fn__space"></div>
|
||||||
|
<button class="b3-button b3-button--text">${window.siyuan.languages.confirm}</button>
|
||||||
|
</div>`,
|
||||||
|
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});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ import {removeLink} from "../protyle/toolbar/Link";
|
||||||
import {alignImgCenter, alignImgLeft} from "../protyle/wysiwyg/commonHotkey";
|
import {alignImgCenter, alignImgLeft} from "../protyle/wysiwyg/commonHotkey";
|
||||||
import {getEnableHTML} from "../protyle/wysiwyg/removeEmbed";
|
import {getEnableHTML} from "../protyle/wysiwyg/removeEmbed";
|
||||||
import {updateTitle} from "../dialog/processSystem";
|
import {updateTitle} from "../dialog/processSystem";
|
||||||
|
import {renameTag} from "../layout/dock/util";
|
||||||
|
import {openGlobalSearch} from "../search/util";
|
||||||
|
|
||||||
export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
|
export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
|
||||||
const nodeElement = hasClosestBlock(element);
|
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: `<div class="fn__hr--small"></div><input class="b3-text-field fn__size200" placeholder="${window.siyuan.languages.tag}"><div class="fn__hr--small"></div>`,
|
||||||
|
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", "<wbr>");
|
||||||
|
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} <b>${window.siyuan.languages.text}</b>`,
|
||||||
|
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", "<wbr>");
|
||||||
|
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) => {
|
const genImageWidthMenu = (label: string, assetElement: HTMLElement, imgElement: HTMLElement, protyle: IProtyle, id: string, nodeElement: HTMLElement, html: string) => {
|
||||||
return {
|
return {
|
||||||
label,
|
label,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import {getSearch, isMobile} from "../../util/functions";
|
||||||
import {isLocalPath, pathPosix} from "../../util/pathName";
|
import {isLocalPath, pathPosix} from "../../util/pathName";
|
||||||
import {genEmptyElement} from "../../block/util";
|
import {genEmptyElement} from "../../block/util";
|
||||||
import {previewImage} from "../preview/image";
|
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 * as dayjs from "dayjs";
|
||||||
import {dropEvent} from "../util/editorCommonEvent";
|
import {dropEvent} from "../util/editorCommonEvent";
|
||||||
import {input} from "./input";
|
import {input} from "./input";
|
||||||
|
|
@ -1158,13 +1158,18 @@ export class WYSIWYG {
|
||||||
protyle.toolbar.showFileAnnotationRef(protyle, target);
|
protyle.toolbar.showFileAnnotationRef(protyle, target);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (types.includes("tag")) {
|
||||||
|
tagMenu(protyle, target);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (types.includes("inline-memo")) {
|
if (types.includes("inline-memo")) {
|
||||||
protyle.toolbar.showRender(protyle, target);
|
protyle.toolbar.showRender(protyle, target);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (types.includes("a")) {
|
if (types.includes("a")) {
|
||||||
linkMenu(protyle, target);
|
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
|
// 阻止 popover
|
||||||
target.setAttribute("prevent-popover", "true");
|
target.setAttribute("prevent-popover", "true");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ import {
|
||||||
goHome,
|
goHome,
|
||||||
upSelect
|
upSelect
|
||||||
} from "./commonHotkey";
|
} from "./commonHotkey";
|
||||||
import {linkMenu, refMenu, setFold, zoomOut} from "../../menus/protyle";
|
import {linkMenu, refMenu, setFold, tagMenu, zoomOut} from "../../menus/protyle";
|
||||||
import {removeEmbed} from "./removeEmbed";
|
import {removeEmbed} from "./removeEmbed";
|
||||||
import {openAttr} from "../../menus/commonMenuItem";
|
import {openAttr} from "../../menus/commonMenuItem";
|
||||||
import {Constants} from "../../constants";
|
import {Constants} from "../../constants";
|
||||||
|
|
@ -534,6 +534,9 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => {
|
||||||
} else if (types.includes("a")) {
|
} else if (types.includes("a")) {
|
||||||
linkMenu(protyle, inlineElement);
|
linkMenu(protyle, inlineElement);
|
||||||
return;
|
return;
|
||||||
|
} else if (types.includes("tag")) {
|
||||||
|
tagMenu(protyle, inlineElement);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue