2023-11-02 11:20:02 +08:00
|
|
|
|
import {
|
|
|
|
|
|
hasClosestBlock,
|
|
|
|
|
|
hasClosestByAttribute,
|
|
|
|
|
|
hasClosestByClassName,
|
2024-04-22 14:15:40 +08:00
|
|
|
|
hasClosestByMatchTag,
|
|
|
|
|
|
hasTopClosestByClassName
|
2023-11-02 11:20:02 +08:00
|
|
|
|
} from "../protyle/util/hasClosest";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {MenuItem} from "./Menu";
|
2023-01-24 15:16:50 +08:00
|
|
|
|
import {focusBlock, focusByRange, focusByWbr, getEditorRange, selectAll,} from "../protyle/util/selection";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {
|
|
|
|
|
|
deleteColumn,
|
|
|
|
|
|
deleteRow,
|
|
|
|
|
|
getColIndex,
|
|
|
|
|
|
insertColumn,
|
|
|
|
|
|
insertRow,
|
|
|
|
|
|
insertRowAbove,
|
|
|
|
|
|
moveColumnToLeft,
|
|
|
|
|
|
moveColumnToRight,
|
|
|
|
|
|
moveRowToDown,
|
|
|
|
|
|
moveRowToUp,
|
|
|
|
|
|
setTableAlign
|
|
|
|
|
|
} from "../protyle/util/table";
|
2023-06-07 10:36:20 +08:00
|
|
|
|
import {mathRender} from "../protyle/render/mathRender";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {transaction, updateTransaction} from "../protyle/wysiwyg/transaction";
|
|
|
|
|
|
import {openMenu} from "./commonMenuItem";
|
|
|
|
|
|
import {fetchPost} from "../util/fetch";
|
|
|
|
|
|
import {Constants} from "../constants";
|
2023-01-01 15:18:32 +08:00
|
|
|
|
import {copyPlainText, readText, setStorageVal, writeText} from "../protyle/util/compatibility";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {preventScroll} from "../protyle/scroll/preventScroll";
|
|
|
|
|
|
import {onGet} from "../protyle/util/onGet";
|
|
|
|
|
|
import {getAllModels} from "../layout/getAll";
|
2023-08-04 14:16:47 +08:00
|
|
|
|
import {pasteAsPlainText, pasteEscaped, pasteText} from "../protyle/util/paste";
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #if !MOBILE
|
2023-12-12 12:09:31 +08:00
|
|
|
|
import {openFileById, updateBacklinkGraph} from "../editor/util";
|
2023-01-16 21:33:20 +08:00
|
|
|
|
import {openGlobalSearch} from "../search/util";
|
2023-02-06 21:50:28 +08:00
|
|
|
|
import {openNewWindowById} from "../window/openNewWindow";
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #endif
|
2023-01-16 21:33:20 +08:00
|
|
|
|
import {getSearch, isMobile} from "../util/functions";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import {removeFoldHeading} from "../protyle/util/heading";
|
2023-06-07 10:36:20 +08:00
|
|
|
|
import {lineNumberRender} from "../protyle/render/highlightRender";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
import * as dayjs from "dayjs";
|
2023-06-07 10:36:20 +08:00
|
|
|
|
import {blockRender} from "../protyle/render/blockRender";
|
2022-07-15 11:22:14 +08:00
|
|
|
|
import {renameAsset} from "../editor/rename";
|
2022-08-15 10:24:37 +08:00
|
|
|
|
import {electronUndo} from "../protyle/undo";
|
2022-08-23 11:55:40 +08:00
|
|
|
|
import {pushBack} from "../mobile/util/MobileBackFoward";
|
2024-05-15 12:14:26 +08:00
|
|
|
|
import {copyPNGByLink, exportAsset} from "./util";
|
2023-10-17 11:37:05 +08:00
|
|
|
|
import {removeInlineType} from "../protyle/toolbar/util";
|
2022-11-21 10:40:29 +08:00
|
|
|
|
import {alignImgCenter, alignImgLeft} from "../protyle/wysiwyg/commonHotkey";
|
2023-12-12 12:09:31 +08:00
|
|
|
|
import {checkFold, renameTag} from "../util/noRelyPCFunction";
|
2023-02-04 10:50:01 +08:00
|
|
|
|
import {hideElements} from "../protyle/ui/hideElements";
|
2023-06-29 18:56:46 +08:00
|
|
|
|
import {emitOpenMenu} from "../plugin/EventBus";
|
2023-08-20 12:41:00 +08:00
|
|
|
|
import {openMobileFileById} from "../mobile/editor";
|
2023-10-11 11:24:29 +08:00
|
|
|
|
import {openBacklink, openGraph} from "../layout/dock/util";
|
2023-10-13 11:08:56 +08:00
|
|
|
|
import {updateHeader} from "../protyle/render/av/row";
|
2023-11-02 11:20:02 +08:00
|
|
|
|
import {renderAssetsPreview} from "../asset/renderAssets";
|
|
|
|
|
|
import {upDownHint} from "../util/upDownHint";
|
|
|
|
|
|
import {hintRenderAssets} from "../protyle/hint/extend";
|
|
|
|
|
|
import {Menu} from "../plugin/Menu";
|
2024-03-30 08:54:07 +08:00
|
|
|
|
import {getFirstBlock} from "../protyle/wysiwyg/getBlock";
|
2024-06-28 22:27:24 +08:00
|
|
|
|
import {popSearch} from "../mobile/menu/search";
|
2023-11-02 11:20:02 +08:00
|
|
|
|
|
|
|
|
|
|
const renderAssetList = (element: Element, k: string, position: IPosition, exts: string[] = []) => {
|
|
|
|
|
|
fetchPost("/api/search/searchAsset", {
|
|
|
|
|
|
k,
|
|
|
|
|
|
exts
|
|
|
|
|
|
}, (response) => {
|
|
|
|
|
|
let searchHTML = "";
|
|
|
|
|
|
response.data.forEach((item: { path: string, hName: string }, index: number) => {
|
|
|
|
|
|
searchHTML += `<div data-value="${item.path}" class="b3-list-item${index === 0 ? " b3-list-item--focus" : ""}"><div class="b3-list-item__text">${item.hName}</div></div>`;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const listElement = element.querySelector(".b3-list");
|
|
|
|
|
|
const previewElement = element.querySelector("#preview");
|
|
|
|
|
|
const inputElement = element.querySelector("input");
|
|
|
|
|
|
listElement.innerHTML = searchHTML || `<li class="b3-list--empty">${window.siyuan.languages.emptyContent}</li>`;
|
|
|
|
|
|
if (response.data.length > 0) {
|
|
|
|
|
|
previewElement.innerHTML = renderAssetsPreview(response.data[0].path);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
previewElement.innerHTML = window.siyuan.languages.emptyContent;
|
|
|
|
|
|
}
|
|
|
|
|
|
/// #if MOBILE
|
|
|
|
|
|
window.siyuan.menus.menu.fullscreen();
|
|
|
|
|
|
/// #else
|
|
|
|
|
|
window.siyuan.menus.menu.popup(position);
|
|
|
|
|
|
/// #endif
|
|
|
|
|
|
if (!k) {
|
|
|
|
|
|
inputElement.select();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-11-02 11:20:47 +08:00
|
|
|
|
};
|
2023-11-02 11:20:02 +08:00
|
|
|
|
|
2024-01-23 10:06:51 +08:00
|
|
|
|
export const assetMenu = (protyle: IProtyle, position: IPosition, callback?: (url: string, name: string) => void, exts?: string[]) => {
|
2024-01-02 12:34:10 +08:00
|
|
|
|
const menu = new Menu("background-asset");
|
|
|
|
|
|
if (menu.isOpen) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-11-02 11:20:02 +08:00
|
|
|
|
menu.addItem({
|
|
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
|
|
|
|
|
label: `<div class="fn__flex" style="max-height: 50vh">
|
|
|
|
|
|
<div class="fn__flex-column" style="${isMobile() ? "width:100%" : "min-width: 260px;max-width:420px"}">
|
|
|
|
|
|
<div class="fn__flex" style="margin: 0 8px 4px 8px">
|
|
|
|
|
|
<input class="b3-text-field fn__flex-1"/>
|
|
|
|
|
|
<span class="fn__space"></span>
|
|
|
|
|
|
<span data-type="previous" class="block__icon block__icon--show"><svg><use xlink:href="#iconLeft"></use></svg></span>
|
|
|
|
|
|
<span class="fn__space"></span>
|
|
|
|
|
|
<span data-type="next" class="block__icon block__icon--show"><svg><use xlink:href="#iconRight"></use></svg></span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="b3-list fn__flex-1 b3-list--background" style="position: relative"><img style="margin: 0 auto;display: block;width: 64px;height: 64px" src="/stage/loading-pure.svg"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="preview" style="width: 360px;display: ${isMobile() || window.outerWidth < window.outerWidth / 2 + 260 ? "none" : "flex"};padding: 8px;overflow: auto;justify-content: center;align-items: center;word-break: break-all;"></div>
|
|
|
|
|
|
</div>`,
|
|
|
|
|
|
bind(element) {
|
|
|
|
|
|
element.style.maxWidth = "none";
|
|
|
|
|
|
const listElement = element.querySelector(".b3-list");
|
|
|
|
|
|
const previewElement = element.querySelector("#preview");
|
|
|
|
|
|
listElement.addEventListener("mouseover", (event) => {
|
|
|
|
|
|
const target = event.target as HTMLElement;
|
|
|
|
|
|
const hoverItemElement = hasClosestByClassName(target, "b3-list-item");
|
|
|
|
|
|
if (!hoverItemElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
previewElement.innerHTML = renderAssetsPreview(hoverItemElement.getAttribute("data-value"));
|
|
|
|
|
|
});
|
|
|
|
|
|
const inputElement = element.querySelector("input");
|
|
|
|
|
|
inputElement.addEventListener("keydown", (event: KeyboardEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const isEmpty = element.querySelector(".b3-list--empty");
|
|
|
|
|
|
if (!isEmpty) {
|
|
|
|
|
|
const currentElement = upDownHint(listElement, event);
|
|
|
|
|
|
if (currentElement) {
|
|
|
|
|
|
previewElement.innerHTML = renderAssetsPreview(currentElement.getAttribute("data-value"));
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
|
|
if (!isEmpty) {
|
2024-01-23 10:06:51 +08:00
|
|
|
|
const currentElement = element.querySelector(".b3-list-item--focus");
|
2023-11-02 11:20:02 +08:00
|
|
|
|
if (callback) {
|
2024-01-23 10:06:51 +08:00
|
|
|
|
callback(currentElement.getAttribute("data-value"), currentElement.textContent);
|
2023-11-02 11:20:02 +08:00
|
|
|
|
} else {
|
2024-01-23 10:06:51 +08:00
|
|
|
|
hintRenderAssets(currentElement.getAttribute("data-value"), protyle);
|
2023-11-02 11:20:02 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (!callback) {
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 空行处插入 mp3 会多一个空的 mp3 块
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
} else if (event.key === "Escape") {
|
|
|
|
|
|
if (!callback) {
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-01-23 10:06:51 +08:00
|
|
|
|
inputElement.addEventListener("input", (event: InputEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
renderAssetList(element, inputElement.value, position, exts);
|
|
|
|
|
|
});
|
|
|
|
|
|
inputElement.addEventListener("compositionend", (event: InputEvent) => {
|
2023-11-02 11:20:02 +08:00
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
renderAssetList(element, inputElement.value, position, exts);
|
|
|
|
|
|
});
|
|
|
|
|
|
element.lastElementChild.addEventListener("click", (event) => {
|
|
|
|
|
|
const target = event.target as HTMLElement;
|
|
|
|
|
|
const previousElement = hasClosestByAttribute(target, "data-type", "previous");
|
|
|
|
|
|
if (previousElement) {
|
|
|
|
|
|
inputElement.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowUp"}));
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const nextElement = hasClosestByAttribute(target, "data-type", "next");
|
|
|
|
|
|
if (nextElement) {
|
|
|
|
|
|
inputElement.dispatchEvent(new KeyboardEvent("keydown", {key: "ArrowDown"}));
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const listItemElement = hasClosestByClassName(target, "b3-list-item");
|
|
|
|
|
|
if (listItemElement) {
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
const currentURL = listItemElement.getAttribute("data-value");
|
|
|
|
|
|
if (callback) {
|
2024-01-23 10:06:51 +08:00
|
|
|
|
callback(currentURL, listItemElement.textContent);
|
2023-11-02 11:20:02 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
hintRenderAssets(currentURL, protyle);
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
renderAssetList(element, "", position, exts);
|
|
|
|
|
|
}
|
2023-11-02 11:20:47 +08:00
|
|
|
|
});
|
|
|
|
|
|
};
|
2022-05-26 15:18:53 +08:00
|
|
|
|
|
2023-06-29 22:07:41 +08:00
|
|
|
|
export const fileAnnotationRefMenu = (protyle: IProtyle, refElement: HTMLElement) => {
|
|
|
|
|
|
const nodeElement = hasClosestBlock(refElement);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
hideElements(["util", "toolbar", "hint"], protyle);
|
|
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
2024-01-01 00:44:37 +08:00
|
|
|
|
let oldHTML = nodeElement.outerHTML;
|
2023-06-29 22:07:41 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
let anchorElement: HTMLInputElement;
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2023-10-17 11:37:05 +08:00
|
|
|
|
iconHTML: "",
|
2023-11-03 21:11:48 +08:00
|
|
|
|
type: "readonly",
|
2024-01-24 15:36:51 +08:00
|
|
|
|
label: `<div>ID</div>
|
2024-04-12 23:50:24 +08:00
|
|
|
|
<textarea spellcheck="false" rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field" readonly>${refElement.getAttribute("data-id") || ""}</textarea>
|
2023-11-03 21:11:48 +08:00
|
|
|
|
<div class="fn__hr"></div>
|
2024-01-24 15:36:51 +08:00
|
|
|
|
<div>${window.siyuan.languages.anchor}</div>
|
2023-11-03 21:11:48 +08:00
|
|
|
|
<textarea rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field"></textarea>`,
|
2023-06-29 22:07:41 +08:00
|
|
|
|
bind(menuItemElement) {
|
2023-11-22 12:02:32 +08:00
|
|
|
|
menuItemElement.style.maxWidth = "none";
|
2023-11-03 21:11:48 +08:00
|
|
|
|
anchorElement = menuItemElement.querySelectorAll(".b3-text-field")[1] as HTMLInputElement;
|
2023-06-29 22:07:41 +08:00
|
|
|
|
anchorElement.value = refElement.textContent;
|
|
|
|
|
|
const inputEvent = () => {
|
|
|
|
|
|
if (anchorElement.value) {
|
|
|
|
|
|
refElement.innerHTML = Lute.EscapeHTMLStr(anchorElement.value);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
refElement.innerHTML = "*";
|
|
|
|
|
|
}
|
2023-07-01 17:06:28 +08:00
|
|
|
|
};
|
2023-06-29 22:07:41 +08:00
|
|
|
|
anchorElement.addEventListener("input", (event: KeyboardEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
inputEvent();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
});
|
|
|
|
|
|
anchorElement.addEventListener("compositionend", (event: KeyboardEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
inputEvent();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
});
|
|
|
|
|
|
anchorElement.addEventListener("keydown", (event: KeyboardEvent) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (event.key === "Enter" && !event.isComposing) {
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
} else if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-11-03 21:11:48 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
2023-06-29 22:07:41 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-01-01 00:44:37 +08:00
|
|
|
|
label: `${window.siyuan.languages.turnInto} <b>${window.siyuan.languages.text}</b>`,
|
|
|
|
|
|
icon: "iconRefresh",
|
2023-06-29 22:07:41 +08:00
|
|
|
|
click() {
|
2024-01-01 00:44:37 +08:00
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
2024-01-01 11:43:49 +08:00
|
|
|
|
removeInlineType(refElement, "file-annotation-ref", protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-06-29 22:07:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-10-17 11:37:05 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-01-01 00:44:37 +08:00
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
label: window.siyuan.languages.remove,
|
2023-10-17 11:37:05 +08:00
|
|
|
|
click() {
|
2024-01-01 00:44:37 +08:00
|
|
|
|
refElement.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
refElement.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-17 11:37:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-06-29 22:07:41 +08:00
|
|
|
|
|
|
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-fileannotationref",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
element: refElement,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const rect = refElement.getBoundingClientRect();
|
|
|
|
|
|
window.siyuan.menus.menu.popup({
|
|
|
|
|
|
x: rect.left,
|
|
|
|
|
|
y: rect.top + 26,
|
|
|
|
|
|
h: 26
|
|
|
|
|
|
});
|
2024-02-24 21:38:25 +08:00
|
|
|
|
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
|
|
|
|
|
|
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
|
2023-06-29 22:07:41 +08:00
|
|
|
|
anchorElement.select();
|
|
|
|
|
|
window.siyuan.menus.menu.removeCB = () => {
|
|
|
|
|
|
if (nodeElement.outerHTML !== oldHTML) {
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const currentRange = getSelection().rangeCount === 0 ? undefined : getSelection().getRangeAt(0);
|
|
|
|
|
|
if (currentRange && !protyle.element.contains(currentRange.startContainer)) {
|
2024-01-01 00:44:37 +08:00
|
|
|
|
protyle.toolbar.range.selectNodeContents(refElement);
|
|
|
|
|
|
protyle.toolbar.range.collapse(false);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
2023-06-29 22:07:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const refMenu = (protyle: IProtyle, element: HTMLElement) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const nodeElement = hasClosestBlock(element);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-02-04 10:50:01 +08:00
|
|
|
|
hideElements(["util", "toolbar", "hint"], protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const refBlockId = element.getAttribute("data-id");
|
|
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
2022-09-26 16:20:53 +08:00
|
|
|
|
let oldHTML = nodeElement.outerHTML;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
2023-10-14 12:14:12 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2023-11-03 21:11:48 +08:00
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
2023-10-14 12:14:12 +08:00
|
|
|
|
label: `<input style="margin: 4px 0" class="b3-text-field fn__block" placeholder="${window.siyuan.languages.anchor}">`,
|
|
|
|
|
|
bind(menuItemElement) {
|
|
|
|
|
|
const inputElement = menuItemElement.querySelector("input");
|
|
|
|
|
|
inputElement.value = element.getAttribute("data-subtype") === "d" ? "" : element.textContent;
|
|
|
|
|
|
inputElement.addEventListener("input", () => {
|
|
|
|
|
|
if (inputElement.value) {
|
|
|
|
|
|
// 不能使用 textContent,否则 < 会变为 <
|
|
|
|
|
|
element.innerHTML = Lute.EscapeHTMLStr(inputElement.value);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
fetchPost("/api/block/getRefText", {id: refBlockId}, (response) => {
|
|
|
|
|
|
element.innerHTML = response.data;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
element.setAttribute("data-subtype", inputElement.value ? "s" : "d");
|
|
|
|
|
|
});
|
|
|
|
|
|
inputElement.addEventListener("keydown", (event) => {
|
|
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (event.key === "Enter" && !event.isComposing) {
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
} else if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "separator"
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #if !MOBILE
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.openBy,
|
2023-11-03 21:11:48 +08:00
|
|
|
|
icon: "iconOpen",
|
2024-05-10 00:31:29 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.openBy.custom + "/" + window.siyuan.languages.click,
|
2022-09-02 12:17:10 +08:00
|
|
|
|
click() {
|
2024-05-29 11:17:20 +08:00
|
|
|
|
checkFold(refBlockId, (zoomIn, action, isRoot) => {
|
|
|
|
|
|
if (!isRoot) {
|
|
|
|
|
|
action.push(Constants.CB_GET_HL);
|
|
|
|
|
|
}
|
2022-09-02 12:17:10 +08:00
|
|
|
|
openFileById({
|
2023-06-01 20:50:49 +08:00
|
|
|
|
app: protyle.app,
|
2022-09-02 12:17:10 +08:00
|
|
|
|
id: refBlockId,
|
2023-12-09 23:32:33 +08:00
|
|
|
|
action,
|
|
|
|
|
|
zoomIn
|
2022-09-02 12:17:10 +08:00
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.refTab,
|
2023-11-03 21:11:48 +08:00
|
|
|
|
icon: "iconEyeoff",
|
2024-05-10 00:31:29 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.refTab.custom + "/⌘" + window.siyuan.languages.click,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
click() {
|
2023-12-09 23:32:33 +08:00
|
|
|
|
checkFold(refBlockId, (zoomIn) => {
|
2022-06-29 15:36:44 +08:00
|
|
|
|
openFileById({
|
2023-06-01 20:50:49 +08:00
|
|
|
|
app: protyle.app,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
id: refBlockId,
|
2023-12-09 23:32:33 +08:00
|
|
|
|
action: zoomIn ? [Constants.CB_GET_HL, Constants.CB_GET_ALL] : [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT, Constants.CB_GET_ROOTSCROLL],
|
2022-06-29 15:36:44 +08:00
|
|
|
|
keepCursor: true,
|
2023-12-09 23:32:33 +08:00
|
|
|
|
zoomIn
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2022-06-29 15:36:44 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.insertRight,
|
2022-10-24 22:18:53 +08:00
|
|
|
|
icon: "iconLayoutRight",
|
2024-05-10 00:31:29 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.insertRight.custom + "/⌥" + window.siyuan.languages.click,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
click() {
|
2024-05-29 11:17:20 +08:00
|
|
|
|
checkFold(refBlockId, (zoomIn, action, isRoot) => {
|
|
|
|
|
|
if (!isRoot) {
|
|
|
|
|
|
action.push(Constants.CB_GET_HL);
|
|
|
|
|
|
}
|
2022-06-29 15:36:44 +08:00
|
|
|
|
openFileById({
|
2023-06-01 20:50:49 +08:00
|
|
|
|
app: protyle.app,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
id: refBlockId,
|
|
|
|
|
|
position: "right",
|
2023-12-09 23:32:33 +08:00
|
|
|
|
action,
|
|
|
|
|
|
zoomIn
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2022-06-29 15:36:44 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.insertBottom,
|
2022-10-24 22:18:53 +08:00
|
|
|
|
icon: "iconLayoutBottom",
|
2024-05-10 00:31:29 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.insertBottom.custom + (window.siyuan.config.keymap.editor.general.insertBottom.custom ? "/" : "") + "⇧" + window.siyuan.languages.click,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
click() {
|
2024-05-29 11:17:20 +08:00
|
|
|
|
checkFold(refBlockId, (zoomIn, action, isRoot) => {
|
|
|
|
|
|
if (!isRoot) {
|
|
|
|
|
|
action.push(Constants.CB_GET_HL);
|
|
|
|
|
|
}
|
2022-06-29 15:36:44 +08:00
|
|
|
|
openFileById({
|
2023-06-01 20:50:49 +08:00
|
|
|
|
app: protyle.app,
|
2022-06-29 15:36:44 +08:00
|
|
|
|
id: refBlockId,
|
|
|
|
|
|
position: "bottom",
|
2023-12-09 23:32:33 +08:00
|
|
|
|
action,
|
|
|
|
|
|
zoomIn
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
2022-06-29 15:36:44 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-02-06 21:50:28 +08:00
|
|
|
|
/// #if !BROWSER
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.openByNewWindow,
|
2023-02-06 22:01:41 +08:00
|
|
|
|
icon: "iconOpenWindow",
|
2023-02-06 21:50:28 +08:00
|
|
|
|
click() {
|
2023-02-06 21:54:26 +08:00
|
|
|
|
openNewWindowById(refBlockId);
|
2023-02-06 21:50:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #endif
|
2023-10-11 11:24:29 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconLink",
|
|
|
|
|
|
label: window.siyuan.languages.backlinks,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.backlinks.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
openBacklink({
|
|
|
|
|
|
app: protyle.app,
|
|
|
|
|
|
blockId: refBlockId,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconGraph",
|
|
|
|
|
|
label: window.siyuan.languages.graphView,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.graphView.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
openGraph({
|
|
|
|
|
|
app: protyle.app,
|
|
|
|
|
|
blockId: refBlockId,
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
2023-02-06 18:40:31 +08:00
|
|
|
|
/// #endif
|
2023-10-14 12:14:12 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
let submenu: IMenu[] = [];
|
|
|
|
|
|
if (element.getAttribute("data-subtype") === "s") {
|
|
|
|
|
|
submenu.push({
|
|
|
|
|
|
label: window.siyuan.languages.turnToDynamic,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.setAttribute("data-subtype", "d");
|
|
|
|
|
|
fetchPost("/api/block/getRefText", {id: refBlockId}, (response) => {
|
|
|
|
|
|
element.innerHTML = response.data;
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
});
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
submenu.push({
|
|
|
|
|
|
label: window.siyuan.languages.turnToStatic,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.setAttribute("data-subtype", "s");
|
2022-05-26 15:18:53 +08:00
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
2023-10-14 12:14:12 +08:00
|
|
|
|
focusByRange(protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
submenu = submenu.concat([{
|
|
|
|
|
|
label: window.siyuan.languages.text,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
2024-01-01 11:43:49 +08:00
|
|
|
|
removeInlineType(element, "block-ref", protyle.toolbar.range);
|
2023-10-14 12:14:12 +08:00
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}, {
|
|
|
|
|
|
label: "*",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.setAttribute("data-subtype", "s");
|
|
|
|
|
|
element.textContent = "*";
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
focusByRange(protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}, {
|
|
|
|
|
|
label: window.siyuan.languages.text + " *",
|
2022-05-26 15:18:53 +08:00
|
|
|
|
click() {
|
2023-10-14 12:14:12 +08:00
|
|
|
|
element.insertAdjacentHTML("beforebegin", element.innerHTML + " ");
|
2022-05-26 15:18:53 +08:00
|
|
|
|
element.setAttribute("data-subtype", "s");
|
2023-10-14 12:14:12 +08:00
|
|
|
|
element.textContent = "*";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}, {
|
|
|
|
|
|
label: window.siyuan.languages.link,
|
|
|
|
|
|
icon: "iconLink",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.outerHTML = `<span data-type="a" data-href="siyuan://blocks/${element.getAttribute("data-id")}">${element.innerHTML}</span><wbr>`;
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}]);
|
|
|
|
|
|
if (element.parentElement.textContent.trim() === element.textContent.trim() && element.parentElement.tagName === "DIV") {
|
|
|
|
|
|
submenu.push({
|
|
|
|
|
|
label: window.siyuan.languages.blockEmbed,
|
|
|
|
|
|
icon: "iconSQL",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
const html = `<div data-content="select * from blocks where id='${refBlockId}'" data-node-id="${id}" data-type="NodeBlockQueryEmbed" class="render-node" updated="${dayjs().format("YYYYMMDDHHmmss")}">${nodeElement.querySelector(".protyle-attr").outerHTML}</div>`;
|
|
|
|
|
|
nodeElement.outerHTML = html;
|
|
|
|
|
|
updateTransaction(protyle, id, html, oldHTML);
|
|
|
|
|
|
blockRender(protyle, protyle.wysiwyg.element);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
submenu.push({
|
2023-10-14 12:14:12 +08:00
|
|
|
|
label: window.siyuan.languages.defBlock,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
fetchPost("/api/block/swapBlockRef", {
|
|
|
|
|
|
refID: id,
|
|
|
|
|
|
defID: refBlockId,
|
|
|
|
|
|
includeChildren: false
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
submenu.push({
|
|
|
|
|
|
label: window.siyuan.languages.defBlockChildren,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
click() {
|
2023-10-14 12:14:12 +08:00
|
|
|
|
fetchPost("/api/block/swapBlockRef", {
|
|
|
|
|
|
refID: id,
|
|
|
|
|
|
defID: refBlockId,
|
|
|
|
|
|
includeChildren: true
|
|
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-10-14 12:14:12 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.turnInto,
|
|
|
|
|
|
icon: "iconRefresh",
|
|
|
|
|
|
submenu
|
|
|
|
|
|
}).element);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copy,
|
|
|
|
|
|
icon: "iconCopy",
|
|
|
|
|
|
click() {
|
2024-06-28 22:13:37 +08:00
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(element.outerHTML));
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-10-14 12:14:12 +08:00
|
|
|
|
if (!protyle.disabled) {
|
2024-06-28 22:13:37 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(element.outerHTML));
|
|
|
|
|
|
|
|
|
|
|
|
element.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
element.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-10-14 12:14:12 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.remove,
|
|
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
element.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
2024-01-01 00:44:37 +08:00
|
|
|
|
oldHTML = nodeElement.outerHTML;
|
2023-10-14 12:14:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
2023-06-29 18:56:46 +08:00
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-blockref",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
element: element,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-08-02 11:13:11 +08:00
|
|
|
|
const rect = element.getBoundingClientRect();
|
|
|
|
|
|
window.siyuan.menus.menu.popup({
|
|
|
|
|
|
x: rect.left,
|
2022-08-15 11:44:11 +08:00
|
|
|
|
y: rect.top + 26,
|
2022-08-02 11:13:11 +08:00
|
|
|
|
h: 26
|
2022-08-02 11:15:18 +08:00
|
|
|
|
});
|
2024-02-24 21:38:25 +08:00
|
|
|
|
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
|
2024-04-03 10:43:34 +08:00
|
|
|
|
window.siyuan.menus.menu.data = element;
|
2024-02-24 21:38:25 +08:00
|
|
|
|
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
|
2023-10-14 12:14:12 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.element.querySelector("input").select();
|
|
|
|
|
|
window.siyuan.menus.menu.removeCB = () => {
|
|
|
|
|
|
if (nodeElement.outerHTML !== oldHTML) {
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
}
|
|
|
|
|
|
const currentRange = getSelection().rangeCount === 0 ? undefined : getSelection().getRangeAt(0);
|
|
|
|
|
|
if (currentRange && !protyle.element.contains(currentRange.startContainer)) {
|
|
|
|
|
|
protyle.toolbar.range.selectNodeContents(element);
|
|
|
|
|
|
protyle.toolbar.range.collapse(false);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export const contentMenu = (protyle: IProtyle, nodeElement: Element) => {
|
|
|
|
|
|
const range = getEditorRange(nodeElement);
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
2023-08-04 14:16:47 +08:00
|
|
|
|
/// #if MOBILE
|
|
|
|
|
|
protyle.toolbar.showContent(protyle, range, nodeElement);
|
|
|
|
|
|
/// #else
|
2024-06-28 22:58:54 +08:00
|
|
|
|
const oldHTML = nodeElement.outerHTML;
|
2024-07-06 09:57:00 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
2023-04-17 17:51:45 +08:00
|
|
|
|
if (range.toString() !== "" || (range.cloneContents().childNodes[0] as HTMLElement)?.classList?.contains("emoji")) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconCopy",
|
|
|
|
|
|
accelerator: "⌘C",
|
|
|
|
|
|
label: window.siyuan.languages.copy,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
// range 需要重新计算 https://ld246.com/article/1644979219025
|
|
|
|
|
|
focusByRange(getEditorRange(nodeElement));
|
|
|
|
|
|
document.execCommand("copy");
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2022-08-20 13:13:21 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copyPlainText,
|
2022-08-29 12:24:19 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.copyPlainText.custom,
|
2022-08-20 13:13:21 +08:00
|
|
|
|
click() {
|
|
|
|
|
|
focusByRange(getEditorRange(nodeElement));
|
2023-11-24 20:17:08 +08:00
|
|
|
|
copyPlainText(getSelection().getRangeAt(0).toString());
|
2022-08-20 13:13:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2022-11-24 23:57:22 +08:00
|
|
|
|
if (protyle.disabled) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
accelerator: "⌘X",
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
focusByRange(getEditorRange(nodeElement));
|
|
|
|
|
|
document.execCommand("cut");
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
accelerator: "⌫",
|
|
|
|
|
|
label: window.siyuan.languages.delete,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
const currentRange = getEditorRange(nodeElement);
|
|
|
|
|
|
currentRange.insertNode(document.createElement("wbr"));
|
|
|
|
|
|
currentRange.extractContents();
|
|
|
|
|
|
focusByWbr(nodeElement, currentRange);
|
|
|
|
|
|
focusByRange(currentRange);
|
2024-06-28 22:58:54 +08:00
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-11-19 15:49:20 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/9630
|
2023-11-20 12:28:20 +08:00
|
|
|
|
const inlineElement = hasClosestByMatchTag(range.startContainer, "SPAN");
|
2023-11-19 15:49:20 +08:00
|
|
|
|
if (inlineElement) {
|
|
|
|
|
|
const inlineTypes = protyle.toolbar.getCurrentType(range);
|
|
|
|
|
|
if (inlineTypes.includes("code") || inlineTypes.includes("kbd")) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-06-28 22:58:54 +08:00
|
|
|
|
label: window.siyuan.languages.copy,
|
2024-06-29 11:06:38 +08:00
|
|
|
|
icon: "iconCopy",
|
2024-06-28 22:58:54 +08:00
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(inlineElement.outerHTML));
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copyPlainText,
|
2023-11-19 15:49:20 +08:00
|
|
|
|
click() {
|
|
|
|
|
|
copyPlainText(inlineElement.textContent);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2024-06-28 22:58:54 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(inlineElement.outerHTML));
|
|
|
|
|
|
|
|
|
|
|
|
inlineElement.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
inlineElement.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
label: window.siyuan.languages.remove,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
inlineElement.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
inlineElement.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
}).element);
|
2023-11-19 15:49:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-04-18 11:06:33 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.paste,
|
2023-08-04 14:16:47 +08:00
|
|
|
|
icon: "iconPaste",
|
2023-04-18 11:06:33 +08:00
|
|
|
|
accelerator: "⌘V",
|
|
|
|
|
|
async click() {
|
|
|
|
|
|
if (document.queryCommandSupported("paste")) {
|
|
|
|
|
|
document.execCommand("paste");
|
|
|
|
|
|
} else {
|
|
|
|
|
|
try {
|
|
|
|
|
|
const clipText = await readText();
|
|
|
|
|
|
pasteText(protyle, clipText, nodeElement);
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
|
console.log(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.pasteAsPlainText,
|
|
|
|
|
|
accelerator: "⇧⌘V",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
focusByRange(getEditorRange(nodeElement));
|
|
|
|
|
|
pasteAsPlainText(protyle);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.pasteEscaped,
|
2023-08-04 14:16:47 +08:00
|
|
|
|
click() {
|
|
|
|
|
|
pasteEscaped(protyle, nodeElement);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-04-18 11:06:33 +08:00
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.selectAll,
|
2023-08-04 14:16:47 +08:00
|
|
|
|
icon: "iconSelect",
|
2022-05-26 15:18:53 +08:00
|
|
|
|
accelerator: "⌘A",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
selectAll(protyle, nodeElement, range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2024-03-13 08:29:07 +08:00
|
|
|
|
if (nodeElement.classList.contains("table") && !protyle.disabled) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const cellElement = hasClosestByMatchTag(range.startContainer, "TD") || hasClosestByMatchTag(range.startContainer, "TH");
|
|
|
|
|
|
if (cellElement) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
const tableMenus = tableMenu(protyle, nodeElement, cellElement as HTMLTableCellElement, range);
|
|
|
|
|
|
if (tableMenus.insertMenus.length > 0) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
tableMenus.insertMenus.forEach((menuItem) => {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem(menuItem).element);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (tableMenus.removeMenus.length > 0) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
tableMenus.removeMenus.forEach((menuItem) => {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem(menuItem).element);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
}).element);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
type: "submenu",
|
2024-06-25 22:45:15 +08:00
|
|
|
|
icon: "iconMore",
|
|
|
|
|
|
label: window.siyuan.languages.more,
|
|
|
|
|
|
submenu: tableMenus.otherMenus.concat(tableMenus.other2Menus)
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-08-04 14:16:47 +08:00
|
|
|
|
/// #endif
|
2023-06-29 22:07:41 +08:00
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-content",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
range,
|
|
|
|
|
|
element: nodeElement,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-08-20 12:41:00 +08:00
|
|
|
|
export const enterBack = (protyle: IProtyle, id: string) => {
|
|
|
|
|
|
if (!protyle.block.showAll) {
|
|
|
|
|
|
const ids = protyle.path.split("/");
|
|
|
|
|
|
if (ids.length > 2) {
|
|
|
|
|
|
/// #if MOBILE
|
|
|
|
|
|
openMobileFileById(protyle.app, ids[ids.length - 2], [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]);
|
|
|
|
|
|
/// #else
|
|
|
|
|
|
openFileById({
|
|
|
|
|
|
app: protyle.app,
|
|
|
|
|
|
id: ids[ids.length - 2],
|
|
|
|
|
|
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
|
|
|
|
|
|
});
|
|
|
|
|
|
/// #endif
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
zoomOut({protyle, id: protyle.block.parent2ID, focusId: id});
|
|
|
|
|
|
}
|
2023-08-28 23:26:47 +08:00
|
|
|
|
};
|
2023-08-20 12:41:00 +08:00
|
|
|
|
|
2023-06-01 14:56:21 +08:00
|
|
|
|
export const zoomOut = (options: {
|
|
|
|
|
|
protyle: IProtyle,
|
|
|
|
|
|
id: string,
|
|
|
|
|
|
focusId?: string,
|
|
|
|
|
|
isPushBack?: boolean,
|
|
|
|
|
|
callback?: () => void,
|
|
|
|
|
|
reload?: boolean
|
|
|
|
|
|
}) => {
|
|
|
|
|
|
if (options.protyle.options.backlinkData) {
|
2022-10-02 20:56:48 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (typeof options.isPushBack === "undefined") {
|
|
|
|
|
|
options.isPushBack = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (typeof options.reload === "undefined") {
|
|
|
|
|
|
options.reload = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
const breadcrumbHLElement = options.protyle.breadcrumb?.element.querySelector(".protyle-breadcrumb__item--active");
|
|
|
|
|
|
if (!options.reload && breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === options.id) {
|
|
|
|
|
|
if (options.id === options.protyle.block.rootID) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-06-01 14:56:21 +08:00
|
|
|
|
const focusElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId || options.id}"]`);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (focusElement) {
|
|
|
|
|
|
focusBlock(focusElement);
|
|
|
|
|
|
focusElement.scrollIntoView();
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-01-24 15:16:50 +08:00
|
|
|
|
if (window.siyuan.mobile?.editor) {
|
2022-12-31 22:14:42 +08:00
|
|
|
|
window.siyuan.storage[Constants.LOCAL_DOCINFO] = {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
id: options.id,
|
2022-12-31 22:14:42 +08:00
|
|
|
|
};
|
2023-01-01 15:18:32 +08:00
|
|
|
|
setStorageVal(Constants.LOCAL_DOCINFO, window.siyuan.storage[Constants.LOCAL_DOCINFO]);
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (options.isPushBack) {
|
2022-08-23 11:55:40 +08:00
|
|
|
|
pushBack();
|
|
|
|
|
|
}
|
2023-02-14 13:21:21 +08:00
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
fetchPost("/api/filetree/getDoc", {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
id: options.id,
|
|
|
|
|
|
size: options.id === options.protyle.block.rootID ? window.siyuan.config.editor.dynamicLoadBlocks : Constants.SIZE_GET_MAX,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}, getResponse => {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (options.isPushBack) {
|
|
|
|
|
|
onGet({
|
|
|
|
|
|
data: getResponse,
|
|
|
|
|
|
protyle: options.protyle,
|
|
|
|
|
|
action: options.id === options.protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_HTML],
|
2023-08-25 15:47:47 +08:00
|
|
|
|
afterCB: options.callback
|
2023-06-01 14:56:21 +08:00
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
} else {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
onGet({
|
|
|
|
|
|
data: getResponse,
|
|
|
|
|
|
protyle: options.protyle,
|
|
|
|
|
|
action: options.id === options.protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML, Constants.CB_GET_UNUNDO] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO, Constants.CB_GET_HTML],
|
2023-08-25 15:47:47 +08:00
|
|
|
|
afterCB: options.callback
|
2023-06-01 14:56:21 +08:00
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/4874
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (options.focusId) {
|
|
|
|
|
|
const focusElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId}"]`);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (focusElement) {
|
2024-03-30 08:54:07 +08:00
|
|
|
|
// 退出聚焦后块在折叠中 https://github.com/siyuan-note/siyuan/issues/10746
|
2024-03-30 18:18:41 +08:00
|
|
|
|
let showElement = focusElement;
|
2024-03-30 08:54:07 +08:00
|
|
|
|
while (showElement.getBoundingClientRect().height === 0) {
|
|
|
|
|
|
showElement = showElement.parentElement;
|
|
|
|
|
|
}
|
2024-04-01 22:41:10 +08:00
|
|
|
|
if (showElement.classList.contains("protyle-wysiwyg")) {
|
|
|
|
|
|
// 闪卡退出聚焦元素被隐藏 https://github.com/siyuan-note/siyuan/issues/10058#issuecomment-2029524211
|
|
|
|
|
|
showElement = focusElement.previousElementSibling || focusElement.nextElementSibling;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
showElement = getFirstBlock(showElement);
|
|
|
|
|
|
}
|
2024-03-30 08:54:07 +08:00
|
|
|
|
focusBlock(showElement);
|
|
|
|
|
|
showElement.scrollIntoView();
|
2023-06-01 14:56:21 +08:00
|
|
|
|
} else if (options.id === options.protyle.block.rootID) { // 聚焦返回后,该块是动态加载的,但是没加载出来
|
2022-05-26 15:18:53 +08:00
|
|
|
|
fetchPost("/api/filetree/getDoc", {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
id: options.focusId,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
mode: 3,
|
2022-10-30 23:13:41 +08:00
|
|
|
|
size: window.siyuan.config.editor.dynamicLoadBlocks,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}, getFocusResponse => {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
onGet({
|
|
|
|
|
|
data: getFocusResponse,
|
|
|
|
|
|
protyle: options.protyle,
|
|
|
|
|
|
action: options.isPushBack ? [Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO],
|
|
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-08-20 23:35:21 +08:00
|
|
|
|
} else if (options.id !== options.protyle.block.rootID) {
|
2023-08-20 17:41:52 +08:00
|
|
|
|
options.protyle.wysiwyg.element.classList.add("protyle-wysiwyg--animate");
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
|
options.protyle.wysiwyg.element.classList.remove("protyle-wysiwyg--animate");
|
|
|
|
|
|
}, 365);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #if !MOBILE
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (options.protyle.model) {
|
2023-05-16 00:05:18 +08:00
|
|
|
|
const allModels = getAllModels();
|
2023-05-15 11:46:51 +08:00
|
|
|
|
allModels.outline.forEach(item => {
|
2023-06-01 14:56:21 +08:00
|
|
|
|
if (item.blockId === options.protyle.block.rootID) {
|
|
|
|
|
|
item.setCurrent(options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId || options.id}"]`));
|
2023-05-15 11:46:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-06-01 14:56:21 +08:00
|
|
|
|
updateBacklinkGraph(allModels, options.protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2022-06-29 15:36:44 +08:00
|
|
|
|
/// #endif
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const imgMenu = (protyle: IProtyle, range: Range, assetElement: HTMLElement, position: {
|
2023-02-02 18:26:15 +08:00
|
|
|
|
clientX: number,
|
|
|
|
|
|
clientY: number
|
|
|
|
|
|
}) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
const nodeElement = hasClosestBlock(assetElement);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-02-04 10:50:01 +08:00
|
|
|
|
hideElements(["util", "toolbar", "hint"], protyle);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
const imgElement = assetElement.querySelector("img");
|
|
|
|
|
|
const titleElement = assetElement.querySelector(".protyle-action__title") as HTMLElement;
|
2023-02-02 18:26:15 +08:00
|
|
|
|
const html = nodeElement.outerHTML;
|
2023-10-30 10:29:53 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
iconHTML: "",
|
2023-11-03 21:11:48 +08:00
|
|
|
|
type: "readonly",
|
2024-01-24 15:36:51 +08:00
|
|
|
|
label: `<div>${window.siyuan.languages.imageURL}</div>
|
2024-04-12 23:50:24 +08:00
|
|
|
|
<textarea spellcheck="false" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" rows="1" class="b3-text-field">${imgElement.getAttribute("src")}</textarea>
|
2023-11-03 21:11:48 +08:00
|
|
|
|
<div class="fn__hr"></div>
|
2024-01-24 15:36:51 +08:00
|
|
|
|
<div>${window.siyuan.languages.title}</div>
|
2023-11-03 21:11:48 +08:00
|
|
|
|
<textarea style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" rows="1" class="b3-text-field"></textarea>
|
|
|
|
|
|
<div class="fn__hr"></div>
|
2024-01-24 15:36:51 +08:00
|
|
|
|
<div>${window.siyuan.languages.tooltipText}</div>
|
2023-11-03 21:11:48 +08:00
|
|
|
|
<textarea style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" rows="1" class="b3-text-field"></textarea>`,
|
2023-10-30 10:29:53 +08:00
|
|
|
|
bind(element) {
|
2023-11-22 12:02:32 +08:00
|
|
|
|
element.style.maxWidth = "none";
|
2023-11-03 21:11:48 +08:00
|
|
|
|
const textElements = element.querySelectorAll("textarea");
|
|
|
|
|
|
textElements[0].addEventListener("input", (event: InputEvent) => {
|
2023-10-30 10:29:53 +08:00
|
|
|
|
if (event.isComposing) {
|
|
|
|
|
|
return;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-10-30 10:29:53 +08:00
|
|
|
|
const value = (event.target as HTMLInputElement).value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "");
|
|
|
|
|
|
imgElement.setAttribute("src", value);
|
|
|
|
|
|
imgElement.setAttribute("data-src", value);
|
|
|
|
|
|
if (value.startsWith("assets/")) {
|
|
|
|
|
|
const imgNetElement = assetElement.querySelector(".img__net");
|
|
|
|
|
|
if (imgNetElement) {
|
|
|
|
|
|
imgNetElement.remove();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (window.siyuan.config.editor.displayNetImgMark) {
|
|
|
|
|
|
assetElement.querySelector(".protyle-action__drag").insertAdjacentHTML("afterend", '<span class="img__net"><svg><use xlink:href="#iconLanguage"></use></svg></span>');
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-11-03 21:11:48 +08:00
|
|
|
|
textElements[1].value = titleElement.textContent;
|
|
|
|
|
|
textElements[1].addEventListener("input", (event) => {
|
2023-10-30 10:29:53 +08:00
|
|
|
|
const value = (event.target as HTMLInputElement).value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "");
|
|
|
|
|
|
imgElement.setAttribute("title", value);
|
|
|
|
|
|
titleElement.textContent = value;
|
|
|
|
|
|
mathRender(titleElement);
|
|
|
|
|
|
});
|
2023-11-03 21:11:48 +08:00
|
|
|
|
textElements[2].value = imgElement.getAttribute("alt") || "";
|
2023-10-30 10:29:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copy,
|
2022-06-09 11:28:35 +08:00
|
|
|
|
accelerator: "⌘C",
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconCopy",
|
|
|
|
|
|
click() {
|
2024-05-06 12:13:56 +08:00
|
|
|
|
let content = protyle.lute.BlockDOM2StdMd(assetElement.outerHTML);
|
|
|
|
|
|
// The file name encoding is abnormal after copying the image and pasting it https://github.com/siyuan-note/siyuan/issues/11246
|
|
|
|
|
|
content = content.replace(/%20/g, " ");
|
|
|
|
|
|
writeText(content);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-04-22 14:15:40 +08:00
|
|
|
|
label: window.siyuan.languages.copyAsPNG,
|
2023-06-18 23:31:50 +08:00
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.copyBlockRef.custom,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconImage",
|
|
|
|
|
|
click() {
|
2024-05-15 12:14:26 +08:00
|
|
|
|
copyPNGByLink(imgElement.getAttribute("src"));
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-10-30 10:29:53 +08:00
|
|
|
|
if (!protyle.disabled) {
|
2022-07-15 11:22:14 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2023-10-30 10:29:53 +08:00
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
accelerator: "⌘X",
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
2022-07-15 11:22:14 +08:00
|
|
|
|
click() {
|
2024-05-06 12:13:56 +08:00
|
|
|
|
let content = protyle.lute.BlockDOM2StdMd(assetElement.outerHTML);
|
|
|
|
|
|
// The file name encoding is abnormal after copying the image and pasting it https://github.com/siyuan-note/siyuan/issues/11246
|
|
|
|
|
|
content = content.replace(/%20/g, " ");
|
|
|
|
|
|
writeText(content);
|
2023-10-30 10:29:53 +08:00
|
|
|
|
(assetElement as HTMLElement).outerHTML = "<wbr>";
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusByWbr(protyle.wysiwyg.element, range);
|
2022-07-15 11:22:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-10-30 10:29:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
accelerator: "⌫",
|
|
|
|
|
|
label: window.siyuan.languages.delete,
|
|
|
|
|
|
click: function () {
|
|
|
|
|
|
(assetElement as HTMLElement).outerHTML = "<wbr>";
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusByWbr(protyle.wysiwyg.element, range);
|
2023-08-21 13:49:47 +08:00
|
|
|
|
}
|
2023-10-30 10:29:53 +08:00
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
|
|
|
|
|
const imagePath = imgElement.getAttribute("data-src");
|
|
|
|
|
|
if (imagePath.startsWith("assets/")) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.rename,
|
|
|
|
|
|
icon: "iconEdit",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
renameAsset(imagePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
2023-10-30 10:29:53 +08:00
|
|
|
|
/// #if !BROWSER
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: "OCR",
|
|
|
|
|
|
submenu: [{
|
2023-11-03 21:11:48 +08:00
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
2024-04-12 23:50:24 +08:00
|
|
|
|
label: `<textarea spellcheck="false" data-type="ocr" style="margin: 4px 0" rows="1" class="b3-text-field fn__size200" placeholder="${window.siyuan.languages.ocrResult}"></textarea>`,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
bind(element) {
|
2023-11-22 12:02:32 +08:00
|
|
|
|
element.style.maxWidth = "none";
|
2023-10-30 10:29:53 +08:00
|
|
|
|
fetchPost("/api/asset/getImageOCRText", {
|
2024-06-15 17:51:48 +08:00
|
|
|
|
path: imgElement.getAttribute("src")
|
2023-10-30 10:29:53 +08:00
|
|
|
|
}, (response) => {
|
2024-06-24 17:07:39 +08:00
|
|
|
|
const textarea = element.querySelector("textarea");
|
2024-06-16 22:55:22 +08:00
|
|
|
|
textarea.value = response.data.text;
|
|
|
|
|
|
textarea.dataset.ocrText = response.data.text;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-11-03 21:11:48 +08:00
|
|
|
|
}, {
|
|
|
|
|
|
type: "separator"
|
|
|
|
|
|
}, {
|
|
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
label: window.siyuan.languages.reOCR,
|
|
|
|
|
|
click() {
|
2024-06-15 17:51:48 +08:00
|
|
|
|
fetchPost("/api/asset/ocr", {
|
2023-11-03 21:11:48 +08:00
|
|
|
|
path: imgElement.getAttribute("src"),
|
|
|
|
|
|
force: true
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-10-30 10:29:53 +08:00
|
|
|
|
}],
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
/// #endif
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconAlignCenter",
|
|
|
|
|
|
label: window.siyuan.languages.alignCenter,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.alignCenter.custom,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
alignImgCenter(protyle, nodeElement, [assetElement], id, html);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconAlignLeft",
|
|
|
|
|
|
label: window.siyuan.languages.alignLeft,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.alignLeft.custom,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
alignImgLeft(protyle, nodeElement, [assetElement], id, html);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2023-11-06 23:10:57 +08:00
|
|
|
|
const width = assetElement.style.width.endsWith("%") ? parseInt(assetElement.style.width) : 0;
|
2023-10-30 10:29:53 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.width,
|
|
|
|
|
|
submenu: [genImageWidthMenu("25%", assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
genImageWidthMenu("33%", assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
genImageWidthMenu("50%", assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
genImageWidthMenu("67%", assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
genImageWidthMenu("75%", assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
genImageWidthMenu("100%", assetElement, imgElement, protyle, id, nodeElement, html), {
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
}, {
|
2023-11-03 21:11:48 +08:00
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
|
|
|
|
|
label: `<div style="margin: 4px 0;" aria-label="${width === 0 ? window.siyuan.languages.default : width + "%"}" class="b3-tooltips b3-tooltips__n${isMobile() ? "" : " fn__size200"}">
|
2023-10-30 10:29:53 +08:00
|
|
|
|
<input style="box-sizing: border-box" value="${width}" class="b3-slider fn__block" max="100" min="1" step="1" type="range">
|
|
|
|
|
|
</div>`,
|
|
|
|
|
|
bind(element) {
|
|
|
|
|
|
const rangeElement = element.querySelector("input");
|
|
|
|
|
|
rangeElement.addEventListener("input", () => {
|
|
|
|
|
|
assetElement.style.width = rangeElement.value + "%";
|
|
|
|
|
|
imgElement.style.width = "10000px";
|
|
|
|
|
|
rangeElement.parentElement.setAttribute("aria-label", `${rangeElement.value}%`);
|
|
|
|
|
|
});
|
|
|
|
|
|
rangeElement.addEventListener("change", () => {
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
focusBlock(nodeElement);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}, {
|
|
|
|
|
|
type: "separator",
|
|
|
|
|
|
},
|
|
|
|
|
|
genImageWidthMenu(window.siyuan.languages.default, assetElement, imgElement, protyle, id, nodeElement, html),
|
|
|
|
|
|
]
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
2022-07-27 07:20:27 +08:00
|
|
|
|
const imgSrc = imgElement.getAttribute("src");
|
2022-07-27 07:17:45 +08:00
|
|
|
|
if (imgSrc) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
2023-06-01 20:50:49 +08:00
|
|
|
|
openMenu(protyle.app, imgSrc, false, false);
|
2022-07-27 07:17:45 +08:00
|
|
|
|
}
|
2023-08-21 13:49:47 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem(exportAsset(imgElement.getAttribute("data-src"))).element);
|
2023-06-29 18:56:46 +08:00
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-image",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
element: assetElement,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2022-05-26 15:18:53 +08:00
|
|
|
|
window.siyuan.menus.menu.popup({x: position.clientX, y: position.clientY});
|
2024-02-24 21:38:25 +08:00
|
|
|
|
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
|
|
|
|
|
|
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
|
2023-10-30 10:29:53 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
const textElements = window.siyuan.menus.menu.element.querySelectorAll("textarea");
|
|
|
|
|
|
textElements[0].focus();
|
|
|
|
|
|
window.siyuan.menus.menu.removeCB = () => {
|
2024-06-16 22:55:22 +08:00
|
|
|
|
const ocrElement = window.siyuan.menus.menu.element.querySelector('[data-type="ocr"]') as HTMLTextAreaElement;
|
|
|
|
|
|
if (ocrElement && ocrElement.dataset.ocrText !== ocrElement.value) {
|
|
|
|
|
|
fetchPost("/api/asset/setImageOCRText", {
|
|
|
|
|
|
path: imgElement.getAttribute("src"),
|
|
|
|
|
|
text: ocrElement.value
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-10-30 10:29:53 +08:00
|
|
|
|
imgElement.setAttribute("alt", textElements[2].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""));
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const linkMenu = (protyle: IProtyle, linkElement: HTMLElement, focusText = false) => {
|
2022-06-01 23:52:22 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
const nodeElement = hasClosestBlock(linkElement);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-02-04 10:50:01 +08:00
|
|
|
|
hideElements(["util", "toolbar", "hint"], protyle);
|
2022-06-01 23:52:22 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
2024-01-01 11:43:49 +08:00
|
|
|
|
let html = nodeElement.outerHTML;
|
2022-06-01 23:52:22 +08:00
|
|
|
|
const linkAddress = linkElement.getAttribute("data-href");
|
2024-01-01 23:08:28 +08:00
|
|
|
|
let inputElements: NodeListOf<HTMLTextAreaElement>;
|
2024-04-28 12:27:34 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
|
|
|
|
|
label: `<div>${window.siyuan.languages.link}</div>
|
2024-04-12 23:50:24 +08:00
|
|
|
|
<textarea spellcheck="false" rows="1" style="margin:4px 0;width: ${isMobile() ? "200" : "360"}px" class="b3-text-field"></textarea>
|
2023-11-03 20:34:45 +08:00
|
|
|
|
<div class="fn__hr"></div>
|
2024-01-24 15:36:51 +08:00
|
|
|
|
<div>${window.siyuan.languages.anchor}</div>
|
2023-11-03 20:34:45 +08:00
|
|
|
|
<textarea style="width: ${isMobile() ? "200" : "360"}px;margin: 4px 0;" rows="1" class="b3-text-field"></textarea>
|
|
|
|
|
|
<div class="fn__hr"></div>
|
2024-01-24 15:36:51 +08:00
|
|
|
|
<div>${window.siyuan.languages.title}</div>
|
2023-11-03 20:34:45 +08:00
|
|
|
|
<textarea style="width: ${isMobile() ? "200" : "360"}px;margin: 4px 0;" rows="1" class="b3-text-field"></textarea>`,
|
2024-04-28 12:27:34 +08:00
|
|
|
|
bind(element) {
|
|
|
|
|
|
element.style.maxWidth = "none";
|
|
|
|
|
|
inputElements = element.querySelectorAll("textarea");
|
|
|
|
|
|
inputElements[0].value = Lute.UnEscapeHTMLStr(linkAddress) || "";
|
|
|
|
|
|
inputElements[0].addEventListener("keydown", (event) => {
|
|
|
|
|
|
if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
} else if (event.key === "Tab" && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
inputElements[1].focus();
|
|
|
|
|
|
} else if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-11-03 20:34:45 +08:00
|
|
|
|
|
2024-04-28 12:27:34 +08:00
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/6798
|
|
|
|
|
|
let anchor = linkElement.textContent.replace(Constants.ZWSP, "");
|
|
|
|
|
|
if (!anchor && linkAddress) {
|
|
|
|
|
|
anchor = linkAddress.replace("https://", "").replace("http://", "");
|
|
|
|
|
|
if (anchor.length > Constants.SIZE_LINK_TEXT_MAX) {
|
|
|
|
|
|
anchor = anchor.substring(0, Constants.SIZE_LINK_TEXT_MAX) + "...";
|
2022-07-16 17:07:50 +08:00
|
|
|
|
}
|
2024-04-28 12:27:34 +08:00
|
|
|
|
linkElement.innerHTML = Lute.EscapeHTMLStr(anchor);
|
2022-06-01 23:52:22 +08:00
|
|
|
|
}
|
2024-04-28 12:27:34 +08:00
|
|
|
|
inputElements[1].value = anchor;
|
|
|
|
|
|
inputElements[1].addEventListener("compositionend", () => {
|
|
|
|
|
|
linkElement.innerHTML = Lute.EscapeHTMLStr(inputElements[1].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "") || "*");
|
|
|
|
|
|
});
|
|
|
|
|
|
inputElements[1].addEventListener("input", (event: KeyboardEvent) => {
|
|
|
|
|
|
if (!event.isComposing) {
|
|
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/4511
|
|
|
|
|
|
linkElement.innerHTML = Lute.EscapeHTMLStr(inputElements[1].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "")) || "*";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
inputElements[1].addEventListener("keydown", (event) => {
|
|
|
|
|
|
if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
} else if (event.key === "Tab" && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
if (event.shiftKey) {
|
|
|
|
|
|
inputElements[0].focus();
|
|
|
|
|
|
} else {
|
|
|
|
|
|
inputElements[2].focus();
|
|
|
|
|
|
}
|
|
|
|
|
|
} else if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2023-11-03 20:34:45 +08:00
|
|
|
|
|
2024-04-28 12:27:34 +08:00
|
|
|
|
inputElements[2].value = Lute.UnEscapeHTMLStr(linkElement.getAttribute("data-title") || "");
|
|
|
|
|
|
inputElements[2].addEventListener("keydown", (event) => {
|
|
|
|
|
|
if ((event.key === "Enter" || event.key === "Escape") && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
} else if (event.key === "Tab" && event.shiftKey && !event.isComposing) {
|
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
inputElements[1].focus();
|
|
|
|
|
|
} else if (electronUndo(event)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
|
|
|
|
|
}
|
2024-01-01 00:44:37 +08:00
|
|
|
|
if (linkAddress) {
|
|
|
|
|
|
openMenu(protyle.app, linkAddress, false, true);
|
|
|
|
|
|
if (linkAddress?.startsWith("assets/")) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem(exportAsset(linkAddress)).element);
|
2023-08-21 13:49:47 +08:00
|
|
|
|
}
|
2024-01-01 00:44:37 +08:00
|
|
|
|
}
|
2024-04-28 12:27:34 +08:00
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
if (linkAddress?.startsWith("assets/")) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.rename,
|
|
|
|
|
|
icon: "iconEdit",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
renameAsset(linkAddress);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
|
|
|
|
|
if (linkAddress?.startsWith("siyuan://blocks/")) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: `${window.siyuan.languages.turnInto} <b>${window.siyuan.languages.ref}</b>`,
|
|
|
|
|
|
icon: "iconRef",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
linkElement.setAttribute("data-subtype", "s");
|
|
|
|
|
|
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", inputElements[0].value.replace("siyuan://blocks/", ""));
|
|
|
|
|
|
inputElements[0].value = "";
|
|
|
|
|
|
inputElements[2].value = "";
|
|
|
|
|
|
linkElement.removeAttribute("data-href");
|
|
|
|
|
|
linkElement.removeAttribute("data-title");
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
protyle.toolbar.range.selectNode(linkElement);
|
|
|
|
|
|
protyle.toolbar.range.collapse(false);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
html = nodeElement.outerHTML;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
2023-08-21 13:49:47 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-04-28 12:27:34 +08:00
|
|
|
|
label: `${window.siyuan.languages.turnInto} <b>${window.siyuan.languages.text}</b>`,
|
|
|
|
|
|
icon: "iconRefresh",
|
2023-08-21 13:49:47 +08:00
|
|
|
|
click() {
|
2024-04-28 12:27:34 +08:00
|
|
|
|
inputElements[0].value = "";
|
|
|
|
|
|
inputElements[2].value = "";
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
removeInlineType(linkElement, "a", protyle.toolbar.range);
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
html = nodeElement.outerHTML;
|
2023-08-21 13:49:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2024-06-24 17:07:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copy,
|
|
|
|
|
|
icon: "iconCopy",
|
|
|
|
|
|
click() {
|
2024-06-28 22:13:37 +08:00
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(linkElement.outerHTML));
|
2024-06-24 17:07:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
if (!protyle.disabled) {
|
2024-06-28 22:13:37 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(linkElement.outerHTML));
|
|
|
|
|
|
|
|
|
|
|
|
linkElement.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
linkElement.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
html = nodeElement.outerHTML;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2022-08-27 21:26:04 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2024-04-28 12:27:34 +08:00
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
label: window.siyuan.languages.remove,
|
2022-06-01 23:52:22 +08:00
|
|
|
|
click() {
|
2024-04-28 12:27:34 +08:00
|
|
|
|
linkElement.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
linkElement.remove();
|
2022-06-01 23:52:22 +08:00
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
2024-04-28 12:27:34 +08:00
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
2024-01-01 11:43:49 +08:00
|
|
|
|
html = nodeElement.outerHTML;
|
2022-06-01 23:52:22 +08:00
|
|
|
|
}
|
2022-08-27 21:26:04 +08:00
|
|
|
|
}).element);
|
2024-04-28 12:27:34 +08:00
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-link",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
element: linkElement,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
2022-08-16 11:38:30 +08:00
|
|
|
|
}
|
2023-06-29 18:56:46 +08:00
|
|
|
|
}
|
2022-08-02 11:13:11 +08:00
|
|
|
|
const rect = linkElement.getBoundingClientRect();
|
|
|
|
|
|
window.siyuan.menus.menu.popup({
|
|
|
|
|
|
x: rect.left,
|
2022-08-15 11:44:11 +08:00
|
|
|
|
y: rect.top + 26,
|
2022-08-02 11:13:11 +08:00
|
|
|
|
h: 26
|
2022-08-02 11:15:18 +08:00
|
|
|
|
});
|
2024-02-24 21:38:25 +08:00
|
|
|
|
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
|
|
|
|
|
|
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
|
2024-04-28 12:27:34 +08:00
|
|
|
|
if (protyle.disabled) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-04-24 22:35:23 +08:00
|
|
|
|
if (focusText || protyle.lute.GetLinkDest(linkAddress)) {
|
2024-01-01 11:43:49 +08:00
|
|
|
|
inputElements[1].select();
|
2022-06-01 23:52:22 +08:00
|
|
|
|
} else {
|
2024-01-01 11:43:49 +08:00
|
|
|
|
inputElements[0].select();
|
2023-02-02 18:26:15 +08:00
|
|
|
|
}
|
|
|
|
|
|
window.siyuan.menus.menu.removeCB = () => {
|
2024-01-01 11:43:49 +08:00
|
|
|
|
if (inputElements[2].value) {
|
|
|
|
|
|
linkElement.setAttribute("data-title", Lute.EscapeHTMLStr(inputElements[2].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "")));
|
2023-02-02 18:26:15 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
linkElement.removeAttribute("data-title");
|
|
|
|
|
|
}
|
2024-01-01 11:51:54 +08:00
|
|
|
|
if (linkElement.getAttribute("data-type").indexOf("a") > -1) {
|
2024-01-01 11:43:49 +08:00
|
|
|
|
linkElement.setAttribute("data-href", Lute.EscapeHTMLStr(inputElements[0].value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "")));
|
2024-01-01 11:51:54 +08:00
|
|
|
|
} else {
|
2024-01-01 11:43:49 +08:00
|
|
|
|
linkElement.removeAttribute("data-href");
|
|
|
|
|
|
}
|
2023-05-20 11:18:58 +08:00
|
|
|
|
const currentRange = getSelection().rangeCount === 0 ? undefined : getSelection().getRangeAt(0);
|
2024-01-01 11:51:54 +08:00
|
|
|
|
if (currentRange && !protyle.element.contains(currentRange.startContainer)) {
|
2023-02-02 18:26:15 +08:00
|
|
|
|
protyle.toolbar.range.selectNodeContents(linkElement);
|
|
|
|
|
|
protyle.toolbar.range.collapse(false);
|
|
|
|
|
|
focusByRange(protyle.toolbar.range);
|
|
|
|
|
|
}
|
2024-01-01 11:43:49 +08:00
|
|
|
|
if (html !== nodeElement.outerHTML) {
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
}
|
2023-02-02 23:16:18 +08:00
|
|
|
|
};
|
2022-06-01 23:52:22 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const tagMenu = (protyle: IProtyle, tagElement: HTMLElement) => {
|
2023-01-15 22:44:05 +08:00
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
const nodeElement = hasClosestBlock(tagElement);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-02-04 10:50:01 +08:00
|
|
|
|
hideElements(["util", "toolbar", "hint"], protyle);
|
2023-01-15 22:44:05 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
let html = nodeElement.outerHTML;
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
2023-11-03 21:11:48 +08:00
|
|
|
|
iconHTML: "",
|
|
|
|
|
|
type: "readonly",
|
2023-07-07 11:36:57 +08:00
|
|
|
|
label: `<input class="b3-text-field fn__size200" style="margin: 4px 0" placeholder="${window.siyuan.languages.tag}">`,
|
2023-01-15 22:44:05 +08:00
|
|
|
|
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);
|
2023-11-03 21:11:48 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
2024-06-28 22:27:24 +08:00
|
|
|
|
|
2023-01-15 22:44:05 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.search,
|
2024-05-10 00:31:29 +08:00
|
|
|
|
accelerator: window.siyuan.languages.click,
|
2023-01-15 22:44:05 +08:00
|
|
|
|
icon: "iconSearch",
|
|
|
|
|
|
click() {
|
2024-06-28 22:27:24 +08:00
|
|
|
|
/// #if !MOBILE
|
2023-06-01 20:50:49 +08:00
|
|
|
|
openGlobalSearch(protyle.app, `#${tagElement.textContent}#`, false);
|
2024-06-28 22:27:24 +08:00
|
|
|
|
/// #else
|
|
|
|
|
|
popSearch(protyle.app, {
|
|
|
|
|
|
hasReplace: false,
|
|
|
|
|
|
method: 0,
|
|
|
|
|
|
hPath: "",
|
|
|
|
|
|
idPath: [],
|
|
|
|
|
|
k: `#${tagElement.textContent}#`,
|
|
|
|
|
|
r: "",
|
|
|
|
|
|
page: 1,
|
|
|
|
|
|
});
|
|
|
|
|
|
/// #endif
|
2023-01-15 22:44:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
2024-06-28 22:27:24 +08:00
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.rename,
|
|
|
|
|
|
icon: "iconEdit",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
renameTag(tagElement.textContent.replace(Constants.ZWSP, ""));
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element);
|
2023-01-15 22:44:05 +08:00
|
|
|
|
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({
|
2024-06-28 22:27:24 +08:00
|
|
|
|
label: window.siyuan.languages.copy,
|
|
|
|
|
|
icon: "iconCopy",
|
2023-01-15 22:44:05 +08:00
|
|
|
|
click() {
|
2024-06-28 22:27:24 +08:00
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(tagElement.outerHTML));
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(tagElement.outerHTML));
|
|
|
|
|
|
|
|
|
|
|
|
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);
|
2023-01-15 22:44:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
}).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);
|
2023-06-29 18:56:46 +08:00
|
|
|
|
|
|
|
|
|
|
if (protyle?.app?.plugins) {
|
|
|
|
|
|
emitOpenMenu({
|
|
|
|
|
|
plugins: protyle.app.plugins,
|
|
|
|
|
|
type: "open-menu-tag",
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
protyle,
|
|
|
|
|
|
element: tagElement,
|
|
|
|
|
|
},
|
|
|
|
|
|
separatorPosition: "top",
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-01-15 22:44:05 +08:00
|
|
|
|
const rect = tagElement.getBoundingClientRect();
|
|
|
|
|
|
window.siyuan.menus.menu.popup({
|
|
|
|
|
|
x: rect.left,
|
|
|
|
|
|
y: rect.top + 26,
|
|
|
|
|
|
h: 26
|
|
|
|
|
|
});
|
2024-02-24 21:38:25 +08:00
|
|
|
|
const popoverElement = hasTopClosestByClassName(protyle.element, "block__popover", true);
|
|
|
|
|
|
window.siyuan.menus.menu.element.setAttribute("data-from", popoverElement ? popoverElement.dataset.level + "popover" : "app");
|
2023-01-15 22:44:05 +08:00
|
|
|
|
window.siyuan.menus.menu.element.querySelector("input").select();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2024-06-28 22:42:28 +08:00
|
|
|
|
export const inlineMathMenu = (protyle: IProtyle, element: Element) => {
|
|
|
|
|
|
window.siyuan.menus.menu.remove();
|
|
|
|
|
|
const nodeElement = hasClosestBlock(element);
|
|
|
|
|
|
if (!nodeElement) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
const html = nodeElement.outerHTML;
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
label: window.siyuan.languages.copy,
|
|
|
|
|
|
icon: "iconCopy",
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(element.outerHTML));
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
if (!protyle.disabled) {
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconCut",
|
|
|
|
|
|
label: window.siyuan.languages.cut,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
writeText(protyle.lute.BlockDOM2StdMd(element.outerHTML));
|
|
|
|
|
|
|
|
|
|
|
|
element.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
element.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
window.siyuan.menus.menu.append(new MenuItem({
|
|
|
|
|
|
icon: "iconTrashcan",
|
|
|
|
|
|
label: window.siyuan.languages.remove,
|
|
|
|
|
|
click() {
|
|
|
|
|
|
element.insertAdjacentHTML("afterend", "<wbr>");
|
|
|
|
|
|
element.remove();
|
|
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusByWbr(nodeElement, protyle.toolbar.range);
|
|
|
|
|
|
}
|
|
|
|
|
|
}).element);
|
|
|
|
|
|
}
|
|
|
|
|
|
const rect = element.getBoundingClientRect();
|
|
|
|
|
|
window.siyuan.menus.menu.popup({
|
|
|
|
|
|
x: rect.left,
|
|
|
|
|
|
y: rect.top + 26,
|
|
|
|
|
|
h: 26
|
|
|
|
|
|
});
|
2024-07-06 09:57:00 +08:00
|
|
|
|
};
|
2024-06-28 22:42:28 +08:00
|
|
|
|
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const genImageWidthMenu = (label: string, assetElement: HTMLElement, imgElement: HTMLElement, protyle: IProtyle, id: string, nodeElement: HTMLElement, html: string) => {
|
|
|
|
|
|
return {
|
2023-11-03 21:11:48 +08:00
|
|
|
|
iconHTML: "",
|
2022-05-26 15:18:53 +08:00
|
|
|
|
label,
|
|
|
|
|
|
click() {
|
2022-06-10 00:54:53 +08:00
|
|
|
|
nodeElement.setAttribute("updated", dayjs().format("YYYYMMDDHHmmss"));
|
2023-03-08 20:22:05 +08:00
|
|
|
|
if (label === window.siyuan.languages.default) {
|
2024-06-19 11:21:37 +08:00
|
|
|
|
const isCenter = assetElement.style.display === "block" || assetElement.style.minWidth;
|
2023-11-06 23:19:37 +08:00
|
|
|
|
assetElement.removeAttribute("style");
|
2023-03-08 22:34:46 +08:00
|
|
|
|
imgElement.removeAttribute("style");
|
2023-11-06 23:19:37 +08:00
|
|
|
|
if (isCenter) {
|
2024-06-19 11:21:37 +08:00
|
|
|
|
assetElement.style.minWidth = "calc(100% - 0.1em)";
|
2023-11-06 23:19:37 +08:00
|
|
|
|
}
|
2023-03-08 20:22:05 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
assetElement.style.width = label;
|
|
|
|
|
|
imgElement.style.width = "10000px";
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
focusBlock(nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const iframeMenu = (protyle: IProtyle, nodeElement: Element) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
const iframeElement = nodeElement.querySelector("iframe");
|
|
|
|
|
|
let html = nodeElement.outerHTML;
|
|
|
|
|
|
const subMenus: IMenu[] = [{
|
2023-06-15 11:24:27 +08:00
|
|
|
|
iconHTML: "",
|
2023-11-03 21:11:48 +08:00
|
|
|
|
type: "readonly",
|
2024-04-12 23:50:24 +08:00
|
|
|
|
label: `<textarea spellcheck="false" rows="1" class="b3-text-field fn__size200" placeholder="${window.siyuan.languages.link}" style="margin: 4px 0">${iframeElement.getAttribute("src") || ""}</textarea>`,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
bind(element) {
|
2023-11-22 12:02:32 +08:00
|
|
|
|
element.style.maxWidth = "none";
|
2023-02-04 11:32:02 +08:00
|
|
|
|
element.querySelector("textarea").addEventListener("change", (event) => {
|
|
|
|
|
|
const value = (event.target as HTMLTextAreaElement).value.replace(/\n|\r\n|\r|\u2028|\u2029/g, "");
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const biliMatch = value.match(/(?:www\.|\/\/)bilibili\.com\/video\/(\w+)/);
|
|
|
|
|
|
if (value.indexOf("bilibili.com") > -1 && (value.indexOf("bvid=") > -1 || (biliMatch && biliMatch[1]))) {
|
|
|
|
|
|
const params: IObject = {
|
2023-01-16 21:33:20 +08:00
|
|
|
|
bvid: getSearch("bvid", value) || (biliMatch && biliMatch[1]),
|
2022-05-26 15:18:53 +08:00
|
|
|
|
page: "1",
|
|
|
|
|
|
high_quality: "1",
|
|
|
|
|
|
as_wide: "1",
|
2024-03-15 21:04:37 +08:00
|
|
|
|
allowfullscreen: "true",
|
|
|
|
|
|
autoplay: "0"
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
2023-09-02 19:39:03 +08:00
|
|
|
|
// `//player.bilibili.com/player.html?aid=895154192&bvid=BV1NP4y1M72N&cid=562898119&page=1`
|
|
|
|
|
|
// `https://www.bilibili.com/video/BV1ys411472E?t=3.4&p=4`
|
|
|
|
|
|
new URL(value.startsWith("http") ? value : "https:" + value).search.split("&").forEach((item, index) => {
|
2024-03-15 21:04:37 +08:00
|
|
|
|
if (!item) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2023-09-02 19:39:03 +08:00
|
|
|
|
if (index === 0) {
|
|
|
|
|
|
item = item.substr(1);
|
|
|
|
|
|
}
|
|
|
|
|
|
const keyValue = item.split("=");
|
|
|
|
|
|
params[keyValue[0]] = keyValue[1];
|
|
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
let src = "https://player.bilibili.com/player.html?";
|
|
|
|
|
|
const keys = Object.keys(params);
|
|
|
|
|
|
keys.forEach((key, index) => {
|
|
|
|
|
|
src += `${key}=${params[key]}`;
|
|
|
|
|
|
if (index < keys.length - 1) {
|
|
|
|
|
|
src += "&";
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
iframeElement.setAttribute("src", src);
|
|
|
|
|
|
iframeElement.setAttribute("sandbox", "allow-top-navigation-by-user-activation allow-same-origin allow-forms allow-scripts allow-popups");
|
|
|
|
|
|
if (!iframeElement.style.height) {
|
|
|
|
|
|
iframeElement.style.height = "360px";
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!iframeElement.style.width) {
|
|
|
|
|
|
iframeElement.style.width = "640px";
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
iframeElement.setAttribute("src", value);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
html = nodeElement.outerHTML;
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}];
|
2022-07-27 07:17:45 +08:00
|
|
|
|
const iframeSrc = iframeElement.getAttribute("src");
|
|
|
|
|
|
if (iframeSrc) {
|
|
|
|
|
|
subMenus.push({
|
|
|
|
|
|
type: "separator"
|
2022-07-27 07:20:27 +08:00
|
|
|
|
});
|
2023-06-01 20:50:49 +08:00
|
|
|
|
return subMenus.concat(openMenu(protyle.app, iframeSrc, true, false) as IMenu[]);
|
2022-07-27 07:17:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
return subMenus;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2023-06-01 20:50:49 +08:00
|
|
|
|
export const videoMenu = (protyle: IProtyle, nodeElement: Element, type: string) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
const videoElement = nodeElement.querySelector(type === "NodeVideo" ? "video" : "audio");
|
|
|
|
|
|
let html = nodeElement.outerHTML;
|
|
|
|
|
|
const subMenus: IMenu[] = [{
|
2023-07-07 11:36:57 +08:00
|
|
|
|
iconHTML: "",
|
2023-11-03 21:11:48 +08:00
|
|
|
|
type: "readonly",
|
2024-04-12 23:50:24 +08:00
|
|
|
|
label: `<textarea spellcheck="false" rows="1" style="margin: 4px 0" class="b3-text-field" placeholder="${window.siyuan.languages.link}">${videoElement.getAttribute("src")}</textarea>`,
|
2022-05-26 15:18:53 +08:00
|
|
|
|
bind(element) {
|
2023-11-22 12:02:32 +08:00
|
|
|
|
element.style.maxWidth = "none";
|
2023-02-04 11:32:02 +08:00
|
|
|
|
element.querySelector("textarea").addEventListener("change", (event) => {
|
|
|
|
|
|
videoElement.setAttribute("src", (event.target as HTMLTextAreaElement).value.replace(/\n|\r\n|\r|\u2028|\u2029/g, ""));
|
2022-05-26 15:18:53 +08:00
|
|
|
|
updateTransaction(protyle, id, nodeElement.outerHTML, html);
|
|
|
|
|
|
html = nodeElement.outerHTML;
|
|
|
|
|
|
event.stopPropagation();
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
}];
|
2022-07-15 12:07:33 +08:00
|
|
|
|
const src = videoElement.getAttribute("src");
|
2022-07-15 12:01:59 +08:00
|
|
|
|
if (src.startsWith("assets/")) {
|
2022-07-27 07:17:45 +08:00
|
|
|
|
subMenus.push({
|
|
|
|
|
|
type: "separator"
|
2022-07-27 07:20:27 +08:00
|
|
|
|
});
|
2022-07-15 12:01:59 +08:00
|
|
|
|
subMenus.push({
|
|
|
|
|
|
label: window.siyuan.languages.rename,
|
2023-10-23 00:05:57 +08:00
|
|
|
|
icon: "iconEdit",
|
2022-07-15 12:01:59 +08:00
|
|
|
|
click() {
|
|
|
|
|
|
renameAsset(src);
|
|
|
|
|
|
}
|
2022-07-15 12:07:33 +08:00
|
|
|
|
});
|
2022-07-15 12:01:59 +08:00
|
|
|
|
}
|
2022-07-27 07:17:45 +08:00
|
|
|
|
const VideoSrc = videoElement.getAttribute("src");
|
|
|
|
|
|
if (VideoSrc) {
|
2023-08-21 13:49:47 +08:00
|
|
|
|
subMenus.push({
|
|
|
|
|
|
label: window.siyuan.languages.openBy,
|
2023-10-23 00:25:36 +08:00
|
|
|
|
icon: "iconOpen",
|
2023-08-21 13:49:47 +08:00
|
|
|
|
submenu: openMenu(protyle.app, VideoSrc, true, false) as IMenu[]
|
|
|
|
|
|
});
|
2022-07-27 07:17:45 +08:00
|
|
|
|
}
|
2023-08-21 13:49:47 +08:00
|
|
|
|
subMenus.push(exportAsset(src));
|
2022-07-27 07:17:45 +08:00
|
|
|
|
return subMenus;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export const tableMenu = (protyle: IProtyle, nodeElement: Element, cellElement: HTMLTableCellElement, range: Range) => {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
const otherMenus: IMenu[] = [];
|
2022-05-26 15:18:53 +08:00
|
|
|
|
const colIndex = getColIndex(cellElement);
|
|
|
|
|
|
if (cellElement.rowSpan > 1 || cellElement.colSpan > 1) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
label: window.siyuan.languages.cancelMerged,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
const oldHTML = nodeElement.outerHTML;
|
|
|
|
|
|
let rowSpan = cellElement.rowSpan;
|
|
|
|
|
|
let currentRowElement: Element = cellElement.parentElement;
|
|
|
|
|
|
const orgColSpan = cellElement.colSpan;
|
|
|
|
|
|
while (rowSpan > 0 && currentRowElement) {
|
|
|
|
|
|
let currentCellElement = currentRowElement.children[colIndex] as HTMLTableCellElement;
|
|
|
|
|
|
let colSpan = orgColSpan;
|
|
|
|
|
|
while (colSpan > 0 && currentCellElement) {
|
|
|
|
|
|
currentCellElement.classList.remove("fn__none");
|
|
|
|
|
|
currentCellElement.colSpan = 1;
|
|
|
|
|
|
currentCellElement.rowSpan = 1;
|
|
|
|
|
|
currentCellElement = currentCellElement.nextElementSibling as HTMLTableCellElement;
|
|
|
|
|
|
colSpan--;
|
|
|
|
|
|
}
|
|
|
|
|
|
currentRowElement = currentRowElement.nextElementSibling;
|
|
|
|
|
|
rowSpan--;
|
|
|
|
|
|
}
|
|
|
|
|
|
cellElement.rowSpan = 1;
|
|
|
|
|
|
cellElement.colSpan = 1;
|
|
|
|
|
|
if (cellElement.tagName === "TH") {
|
|
|
|
|
|
let prueTrElement: HTMLElement;
|
|
|
|
|
|
Array.from(nodeElement.querySelectorAll("thead tr")).find((item: HTMLElement) => {
|
|
|
|
|
|
prueTrElement = item;
|
|
|
|
|
|
Array.from(item.children).forEach((cellElement: HTMLTableCellElement) => {
|
|
|
|
|
|
if (cellElement.rowSpan !== 1 || cellElement.classList.contains("fn__none")) {
|
|
|
|
|
|
prueTrElement = undefined;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (prueTrElement) {
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (prueTrElement) {
|
|
|
|
|
|
const tbodyElement = nodeElement.querySelector("tbody");
|
|
|
|
|
|
const theadElement = nodeElement.querySelector("thead");
|
|
|
|
|
|
while (!prueTrElement.isSameNode(theadElement.lastElementChild)) {
|
|
|
|
|
|
tbodyElement.insertAdjacentElement("afterbegin", theadElement.lastElementChild);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2022-10-21 11:35:12 +08:00
|
|
|
|
focusByRange(range);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, oldHTML);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
const thMatchElement = nodeElement.querySelectorAll("col")[colIndex];
|
2022-12-29 15:13:37 +08:00
|
|
|
|
if (thMatchElement.style.width || thMatchElement.style.minWidth) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
label: window.siyuan.languages.useDefaultWidth,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
const html = nodeElement.outerHTML;
|
|
|
|
|
|
thMatchElement.style.width = "";
|
2022-12-29 15:13:37 +08:00
|
|
|
|
thMatchElement.style.minWidth = "";
|
2022-05-26 15:18:53 +08:00
|
|
|
|
updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, html);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2023-05-29 11:20:08 +08:00
|
|
|
|
const isPinHead = nodeElement.getAttribute("custom-pinthead");
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({
|
2023-12-05 22:38:28 +08:00
|
|
|
|
icon: isPinHead ? "iconUnpin" : "iconPin",
|
2023-05-25 11:50:12 +08:00
|
|
|
|
label: isPinHead ? window.siyuan.languages.unpinTableHead : window.siyuan.languages.pinTableHead,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
const html = nodeElement.outerHTML;
|
|
|
|
|
|
if (isPinHead) {
|
2023-05-29 11:20:08 +08:00
|
|
|
|
nodeElement.removeAttribute("custom-pinthead");
|
2023-05-25 11:50:12 +08:00
|
|
|
|
} else {
|
2023-05-29 11:20:08 +08:00
|
|
|
|
nodeElement.setAttribute("custom-pinthead", "true");
|
2023-05-25 11:50:12 +08:00
|
|
|
|
}
|
|
|
|
|
|
updateTransaction(protyle, nodeElement.getAttribute("data-node-id"), nodeElement.outerHTML, html);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({type: "separator"});
|
|
|
|
|
|
otherMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconAlignLeft",
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.alignLeft.custom,
|
|
|
|
|
|
label: window.siyuan.languages.alignLeft,
|
|
|
|
|
|
click: () => {
|
2022-06-12 22:06:19 +08:00
|
|
|
|
setTableAlign(protyle, [cellElement], nodeElement, "left", range);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconAlignCenter",
|
|
|
|
|
|
label: window.siyuan.languages.alignCenter,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.alignCenter.custom,
|
|
|
|
|
|
click: () => {
|
2022-06-12 22:06:19 +08:00
|
|
|
|
setTableAlign(protyle, [cellElement], nodeElement, "center", range);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-06-25 22:45:15 +08:00
|
|
|
|
otherMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconAlignRight",
|
|
|
|
|
|
label: window.siyuan.languages.alignRight,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.general.alignRight.custom,
|
|
|
|
|
|
click: () => {
|
2022-06-12 22:06:19 +08:00
|
|
|
|
setTableAlign(protyle, [cellElement], nodeElement, "right", range);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-06-25 22:45:15 +08:00
|
|
|
|
const menus: IMenu[] = [];
|
2024-07-06 09:57:00 +08:00
|
|
|
|
menus.push(...otherMenus);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
menus.push({
|
|
|
|
|
|
type: "separator"
|
|
|
|
|
|
});
|
|
|
|
|
|
const tableElement = nodeElement.querySelector("table");
|
|
|
|
|
|
const hasNone = cellElement.parentElement.querySelector(".fn__none");
|
|
|
|
|
|
let hasColSpan = false;
|
|
|
|
|
|
let hasRowSpan = false;
|
|
|
|
|
|
Array.from(cellElement.parentElement.children).forEach((item: HTMLTableCellElement) => {
|
|
|
|
|
|
if (item.colSpan > 1) {
|
|
|
|
|
|
hasColSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (item.rowSpan > 1) {
|
|
|
|
|
|
hasRowSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
let previousHasNone: false | Element = false;
|
|
|
|
|
|
let previousHasColSpan = false;
|
|
|
|
|
|
let previousHasRowSpan = false;
|
|
|
|
|
|
let previousRowElement = cellElement.parentElement.previousElementSibling;
|
|
|
|
|
|
if (!previousRowElement && cellElement.parentElement.parentElement.tagName === "TBODY") {
|
|
|
|
|
|
previousRowElement = tableElement.querySelector("thead").lastElementChild;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (previousRowElement) {
|
|
|
|
|
|
previousHasNone = previousRowElement.querySelector(".fn__none");
|
|
|
|
|
|
Array.from(previousRowElement.children).forEach((item: HTMLTableCellElement) => {
|
|
|
|
|
|
if (item.colSpan > 1) {
|
|
|
|
|
|
previousHasColSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (item.rowSpan > 1) {
|
|
|
|
|
|
previousHasRowSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
let nextHasNone: false | Element = false;
|
|
|
|
|
|
let nextHasColSpan = false;
|
|
|
|
|
|
let nextHasRowSpan = false;
|
|
|
|
|
|
let nextRowElement = cellElement.parentElement.nextElementSibling;
|
|
|
|
|
|
if (!nextRowElement && cellElement.parentElement.parentElement.tagName === "THEAD") {
|
|
|
|
|
|
nextRowElement = tableElement.querySelector("tbody")?.firstElementChild;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (nextRowElement) {
|
|
|
|
|
|
nextHasNone = nextRowElement.querySelector(".fn__none");
|
|
|
|
|
|
Array.from(nextRowElement.children).forEach((item: HTMLTableCellElement) => {
|
|
|
|
|
|
if (item.colSpan > 1) {
|
|
|
|
|
|
nextHasColSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (item.rowSpan > 1) {
|
|
|
|
|
|
nextHasRowSpan = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
let colIsPure = true;
|
|
|
|
|
|
Array.from(tableElement.rows).find(item => {
|
|
|
|
|
|
const cellElement = item.cells[colIndex];
|
|
|
|
|
|
if (cellElement.classList.contains("fn__none") || cellElement.colSpan > 1 || cellElement.rowSpan > 1) {
|
|
|
|
|
|
colIsPure = false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
let nextColIsPure = true;
|
|
|
|
|
|
Array.from(tableElement.rows).find(item => {
|
|
|
|
|
|
const cellElement = item.cells[colIndex + 1];
|
|
|
|
|
|
if (cellElement && (cellElement.classList.contains("fn__none") || cellElement.colSpan > 1 || cellElement.rowSpan > 1)) {
|
|
|
|
|
|
nextColIsPure = false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
let previousColIsPure = true;
|
|
|
|
|
|
Array.from(tableElement.rows).find(item => {
|
|
|
|
|
|
const cellElement = item.cells[colIndex - 1];
|
|
|
|
|
|
if (cellElement && (cellElement.classList.contains("fn__none") || cellElement.colSpan > 1 || cellElement.rowSpan > 1)) {
|
|
|
|
|
|
previousColIsPure = false;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2024-07-06 09:57:00 +08:00
|
|
|
|
const insertMenus = [];
|
2024-06-25 22:45:15 +08:00
|
|
|
|
insertMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconBefore",
|
|
|
|
|
|
label: window.siyuan.languages.insertRowAbove,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.insertRowAbove.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
insertRowAbove(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
if (!nextHasNone || (nextHasNone && !nextHasRowSpan && nextHasColSpan)) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
insertMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconAfter",
|
|
|
|
|
|
label: window.siyuan.languages.insertRowBelow,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.insertRowBelow.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
insertRow(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colIsPure || previousColIsPure) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
insertMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconInsertLeft",
|
|
|
|
|
|
label: window.siyuan.languages.insertColumnLeft,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.insertColumnLeft.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
insertColumn(protyle, nodeElement, cellElement, "beforebegin", range);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colIsPure || nextColIsPure) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
insertMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconInsertRight",
|
|
|
|
|
|
label: window.siyuan.languages.insertColumnRight,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.insertColumnRight.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
insertColumn(protyle, nodeElement, cellElement, "afterend", range);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-07-06 09:57:00 +08:00
|
|
|
|
menus.push(...insertMenus);
|
|
|
|
|
|
const other2Menus: IMenu[] = [];
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (((!hasNone || (hasNone && !hasRowSpan && hasColSpan)) &&
|
|
|
|
|
|
(!previousHasNone || (previousHasNone && !previousHasRowSpan && previousHasColSpan))) ||
|
|
|
|
|
|
((!hasNone || (hasNone && !hasRowSpan && hasColSpan)) &&
|
|
|
|
|
|
(!nextHasNone || (nextHasNone && !nextHasRowSpan && nextHasColSpan))) ||
|
|
|
|
|
|
(colIsPure && previousColIsPure) ||
|
|
|
|
|
|
(colIsPure && nextColIsPure)
|
|
|
|
|
|
) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
other2Menus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
type: "separator"
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((!hasNone || (hasNone && !hasRowSpan && hasColSpan)) &&
|
|
|
|
|
|
(!previousHasNone || (previousHasNone && !previousHasRowSpan && previousHasColSpan))) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
other2Menus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconUp",
|
|
|
|
|
|
label: window.siyuan.languages.moveToUp,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.moveToUp.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
moveRowToUp(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if ((!hasNone || (hasNone && !hasRowSpan && hasColSpan)) &&
|
|
|
|
|
|
(!nextHasNone || (nextHasNone && !nextHasRowSpan && nextHasColSpan))) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
other2Menus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconDown",
|
|
|
|
|
|
label: window.siyuan.languages.moveToDown,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.moveToDown.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
moveRowToDown(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colIsPure && previousColIsPure) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
other2Menus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconLeft",
|
|
|
|
|
|
label: window.siyuan.languages.moveToLeft,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.moveToLeft.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
moveColumnToLeft(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colIsPure && nextColIsPure) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
other2Menus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconRight",
|
|
|
|
|
|
label: window.siyuan.languages.moveToRight,
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table.moveToRight.custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
moveColumnToRight(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-06-25 22:45:15 +08:00
|
|
|
|
menus.push(...other2Menus);
|
2022-06-10 16:35:08 +08:00
|
|
|
|
if ((cellElement.parentElement.parentElement.tagName !== "THEAD" &&
|
|
|
|
|
|
((!hasNone && !hasRowSpan) || (hasNone && !hasRowSpan && hasColSpan))) || colIsPure) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
menus.push({
|
|
|
|
|
|
type: "separator"
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-07-06 09:57:00 +08:00
|
|
|
|
const removeMenus = [];
|
2022-06-10 16:35:08 +08:00
|
|
|
|
if (cellElement.parentElement.parentElement.tagName !== "THEAD" &&
|
|
|
|
|
|
((!hasNone && !hasRowSpan) || (hasNone && !hasRowSpan && hasColSpan))) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
removeMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconDeleteRow",
|
|
|
|
|
|
label: window.siyuan.languages["delete-row"],
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table["delete-row"].custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
deleteRow(protyle, range, cellElement, nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
if (colIsPure) {
|
2024-06-25 22:45:15 +08:00
|
|
|
|
removeMenus.push({
|
2022-05-26 15:18:53 +08:00
|
|
|
|
icon: "iconDeleteColumn",
|
|
|
|
|
|
label: window.siyuan.languages["delete-column"],
|
|
|
|
|
|
accelerator: window.siyuan.config.keymap.editor.table["delete-column"].custom,
|
|
|
|
|
|
click: () => {
|
|
|
|
|
|
deleteColumn(protyle, range, nodeElement, cellElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-06-25 22:45:15 +08:00
|
|
|
|
menus.push(...removeMenus);
|
|
|
|
|
|
return {menus, removeMenus, insertMenus, otherMenus, other2Menus};
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
2024-06-29 11:06:38 +08:00
|
|
|
|
export const setFold = (protyle: IProtyle, nodeElement: Element, isOpen?: boolean, isRemove?: boolean, addLoading = true) => {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (nodeElement.getAttribute("data-type") === "NodeListItem" && nodeElement.childElementCount < 4) {
|
|
|
|
|
|
// 没有子列表或多个块的列表项不进行折叠
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2022-10-08 16:13:24 +08:00
|
|
|
|
if (nodeElement.getAttribute("data-type") === "NodeThematicBreak") {
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2024-03-25 17:38:13 +08:00
|
|
|
|
const hasFold = nodeElement.getAttribute("fold") === "1";
|
2024-03-24 22:16:49 +08:00
|
|
|
|
if (hasFold) {
|
2022-05-26 15:18:53 +08:00
|
|
|
|
if (typeof isOpen === "boolean" && !isOpen) {
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
nodeElement.removeAttribute("fold");
|
|
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/4411
|
|
|
|
|
|
nodeElement.querySelectorAll(".protyle-linenumber").forEach((item: HTMLElement) => {
|
|
|
|
|
|
lineNumberRender(item);
|
|
|
|
|
|
});
|
|
|
|
|
|
} else {
|
|
|
|
|
|
if (typeof isOpen === "boolean" && isOpen) {
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
nodeElement.setAttribute("fold", "1");
|
|
|
|
|
|
// 光标在子列表中,再次 focus 段尾的时候不会变 https://ld246.com/article/1647099132461
|
|
|
|
|
|
if (getSelection().rangeCount > 0) {
|
|
|
|
|
|
const range = getSelection().getRangeAt(0);
|
|
|
|
|
|
const blockElement = hasClosestBlock(range.startContainer);
|
|
|
|
|
|
if (blockElement && blockElement.getBoundingClientRect().width === 0) {
|
2022-09-06 23:03:43 +08:00
|
|
|
|
// https://github.com/siyuan-note/siyuan/issues/5833
|
|
|
|
|
|
focusBlock(nodeElement, undefined, false);
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-01-13 22:34:46 +08:00
|
|
|
|
nodeElement.querySelectorAll(".img--select, .av__cell--select, .av__cell--active, .av__row--select").forEach((item: HTMLElement) => {
|
2023-10-13 10:14:11 +08:00
|
|
|
|
if (item.classList.contains("av__row--select")) {
|
2023-10-13 11:55:51 +08:00
|
|
|
|
item.classList.remove("av__row--select");
|
2024-01-17 11:46:08 +08:00
|
|
|
|
item.querySelector(".av__firstcol use").setAttribute("xlink:href", "#iconUncheck");
|
2023-10-13 10:14:11 +08:00
|
|
|
|
updateHeader(item);
|
2023-10-13 11:55:51 +08:00
|
|
|
|
} else {
|
2024-01-13 22:34:46 +08:00
|
|
|
|
item.querySelector(".av__drag-fill")?.remove();
|
|
|
|
|
|
item.classList.remove("img--select", "av__cell--select", "av__cell--active");
|
2023-10-13 10:14:11 +08:00
|
|
|
|
}
|
2023-01-30 10:48:02 +08:00
|
|
|
|
});
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
const id = nodeElement.getAttribute("data-node-id");
|
|
|
|
|
|
if (nodeElement.getAttribute("data-type") === "NodeHeading") {
|
2024-03-24 22:16:49 +08:00
|
|
|
|
if (hasFold) {
|
2024-06-29 11:06:38 +08:00
|
|
|
|
if (addLoading) {
|
|
|
|
|
|
nodeElement.insertAdjacentHTML("beforeend", '<div spin="1" style="text-align: center"><img width="24px" height="24px" src="/stage/loading-pure.svg"></div>');
|
|
|
|
|
|
}
|
2022-05-26 15:18:53 +08:00
|
|
|
|
transaction(protyle, [{
|
|
|
|
|
|
action: "unfoldHeading",
|
|
|
|
|
|
id,
|
|
|
|
|
|
data: isRemove ? "remove" : undefined,
|
|
|
|
|
|
}], [{
|
|
|
|
|
|
action: "foldHeading",
|
|
|
|
|
|
id
|
|
|
|
|
|
}]);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
transaction(protyle, [{
|
|
|
|
|
|
action: "foldHeading",
|
|
|
|
|
|
id
|
|
|
|
|
|
}], [{
|
|
|
|
|
|
action: "unfoldHeading",
|
|
|
|
|
|
id
|
|
|
|
|
|
}]);
|
|
|
|
|
|
removeFoldHeading(nodeElement);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
transaction(protyle, [{
|
|
|
|
|
|
action: "setAttrs",
|
|
|
|
|
|
id,
|
2024-03-24 22:16:49 +08:00
|
|
|
|
data: JSON.stringify({fold: hasFold ? "" : "1"})
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}], [{
|
|
|
|
|
|
action: "setAttrs",
|
|
|
|
|
|
id,
|
2024-03-24 22:16:49 +08:00
|
|
|
|
data: JSON.stringify({fold: hasFold ? "1" : ""})
|
2022-05-26 15:18:53 +08:00
|
|
|
|
}]);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 折叠后,防止滚动条滚动后调用 get 请求 https://github.com/siyuan-note/siyuan/issues/2248
|
|
|
|
|
|
preventScroll(protyle);
|
2024-03-24 22:16:49 +08:00
|
|
|
|
return !hasFold ? 1 : 0;
|
2022-05-26 15:18:53 +08:00
|
|
|
|
};
|