mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-01-24 17:26:10 +01:00
This commit is contained in:
parent
01ee358a61
commit
ced6f0165d
2 changed files with 157 additions and 120 deletions
|
|
@ -3,6 +3,7 @@ import {hasClosestBlock, hasClosestByAttribute, hasClosestByClassName} from "../
|
|||
import {fetchSyncPost} from "../util/fetch";
|
||||
import {hideTooltip, showTooltip} from "../dialog/tooltip";
|
||||
|
||||
let popoverTargetElement: HTMLElement
|
||||
export const initBlockPopover = () => {
|
||||
let timeout: number;
|
||||
let timeoutHide: number;
|
||||
|
|
@ -35,6 +36,17 @@ export const initBlockPopover = () => {
|
|||
hideTooltip();
|
||||
}
|
||||
|
||||
if (window.siyuan.config.editor.floatWindowMode === 1) {
|
||||
if (!getTarget(event, aElement)) {
|
||||
hidePopover(event);
|
||||
return;
|
||||
}
|
||||
if (window.siyuan.ctrlIsPressed) {
|
||||
showPopover()
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(timeout);
|
||||
clearTimeout(timeoutHide);
|
||||
timeoutHide = window.setTimeout(() => {
|
||||
|
|
@ -45,9 +57,9 @@ export const initBlockPopover = () => {
|
|||
) {
|
||||
// b3-menu 需要处理,(( 后的 hint 上的图表移上去需显示预览
|
||||
// gutter & mindmap & 文件树上的数字 & 关系图节点不处理
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
let popoverTargetElement = hasClosestByAttribute(event.target, "data-type", "block-ref") as HTMLElement ||
|
||||
popoverTargetElement = hasClosestByAttribute(event.target, "data-type", "block-ref") as HTMLElement ||
|
||||
hasClosestByAttribute(event.target, "data-type", "virtual-block-ref") as HTMLElement;
|
||||
if (popoverTargetElement && popoverTargetElement.classList.contains("b3-tooltips")) {
|
||||
popoverTargetElement = undefined;
|
||||
|
|
@ -60,133 +72,154 @@ export const initBlockPopover = () => {
|
|||
popoverTargetElement = linkElement;
|
||||
}
|
||||
if (!popoverTargetElement) {
|
||||
const blockElement = hasClosestByClassName(event.target, "block__popover", true);
|
||||
const maxEditLevels: { [key: string]: number } = {oid: 0};
|
||||
window.siyuan.blockPanels.forEach((item) => {
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "true") {
|
||||
const level = parseInt(item.element.getAttribute("data-level"));
|
||||
const oid = item.element.getAttribute("data-oid");
|
||||
if (maxEditLevels[oid]) {
|
||||
if (level > maxEditLevels[oid]) {
|
||||
maxEditLevels[oid] = level;
|
||||
}
|
||||
} else {
|
||||
maxEditLevels[oid] = level; // 不能为1,否则 pin 住第三层,第二层会消失
|
||||
}
|
||||
}
|
||||
});
|
||||
if (blockElement) {
|
||||
for (let i = 0; i < window.siyuan.blockPanels.length; i++) {
|
||||
const item = window.siyuan.blockPanels[i];
|
||||
if (item.targetElement &&
|
||||
parseInt(item.element.getAttribute("data-level")) > (maxEditLevels[item.element.getAttribute("data-oid")] || 0) &&
|
||||
item.element.getAttribute("data-pin") === "false" &&
|
||||
parseInt(item.element.getAttribute("data-level")) > parseInt(blockElement.getAttribute("data-level"))) {
|
||||
item.destroy();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < window.siyuan.blockPanels.length; i++) {
|
||||
const item = window.siyuan.blockPanels[i];
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "false" &&
|
||||
parseInt(item.element.getAttribute("data-level")) > (maxEditLevels[item.element.getAttribute("data-oid")] || 0)) {
|
||||
item.destroy();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
hidePopover(event)
|
||||
return;
|
||||
}
|
||||
if (!popoverTargetElement && !aElement) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
}, 200);
|
||||
timeout = window.setTimeout(async () => {
|
||||
if (hasClosestByClassName(event.target, "history__repo", true)) {
|
||||
if (!getTarget(event, aElement)) {
|
||||
return;
|
||||
}
|
||||
let popoverTargetElement = hasClosestByAttribute(event.target, "data-type", "block-ref") as HTMLElement ||
|
||||
hasClosestByAttribute(event.target, "data-type", "virtual-block-ref") as HTMLElement;
|
||||
if (popoverTargetElement && popoverTargetElement.classList.contains("b3-tooltips")) {
|
||||
popoverTargetElement = undefined;
|
||||
}
|
||||
if (!popoverTargetElement) {
|
||||
popoverTargetElement = hasClosestByClassName(event.target, "popover__block") as HTMLElement;
|
||||
}
|
||||
if (!popoverTargetElement && aElement && aElement.getAttribute("data-href")?.startsWith("siyuan://blocks") && aElement.getAttribute("prevent-popover") !== "true") {
|
||||
popoverTargetElement = aElement;
|
||||
}
|
||||
if (!popoverTargetElement || window.siyuan.altIsPressed || window.siyuan.shiftIsPressed || window.siyuan.ctrlIsPressed ||
|
||||
(popoverTargetElement && popoverTargetElement.getAttribute("prevent-popover") === "true")) {
|
||||
return;
|
||||
}
|
||||
// https://github.com/siyuan-note/siyuan/issues/4314
|
||||
if (popoverTargetElement && getSelection().rangeCount > 0) {
|
||||
const range = getSelection().getRangeAt(0);
|
||||
if (range.toString() !== "" && popoverTargetElement.contains(range.startContainer)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
clearTimeout(timeoutHide);
|
||||
let ids: string[];
|
||||
let defIds: string[];
|
||||
const dataId = popoverTargetElement.getAttribute("data-id");
|
||||
if (dataId) {
|
||||
// backlink/util/hint/正文标题 上的弹层
|
||||
if (dataId.startsWith("[")) {
|
||||
ids = JSON.parse(dataId);
|
||||
} else {
|
||||
ids = [dataId];
|
||||
}
|
||||
defIds = JSON.parse(popoverTargetElement.getAttribute("data-defids") || "[]");
|
||||
} else if (popoverTargetElement.getAttribute("data-type")?.indexOf("virtual-block-ref") > -1) {
|
||||
const nodeElement = hasClosestBlock(popoverTargetElement);
|
||||
if (nodeElement) {
|
||||
const postResponse = await fetchSyncPost("/api/block/getBlockDefIDsByRefText", {
|
||||
anchor: popoverTargetElement.textContent,
|
||||
excludeIDs: [nodeElement.getAttribute("data-node-id")]
|
||||
});
|
||||
ids = postResponse.data;
|
||||
}
|
||||
} else if (popoverTargetElement.getAttribute("data-type")?.split(" ").includes("a")) {
|
||||
// 以思源协议开头的链接
|
||||
ids = [popoverTargetElement.getAttribute("data-href").substr(16, 22)];
|
||||
} else {
|
||||
// pdf
|
||||
let targetId;
|
||||
let url = "/api/block/getRefIDs";
|
||||
if (popoverTargetElement.classList.contains("protyle-attr--refcount")) {
|
||||
// 编辑器中的引用数
|
||||
targetId = popoverTargetElement.parentElement.parentElement.getAttribute("data-node-id");
|
||||
} else if (popoverTargetElement.classList.contains("pdf__rect")) {
|
||||
targetId = popoverTargetElement.getAttribute("data-node-id");
|
||||
url = "/api/block/getRefIDsByFileAnnotationID";
|
||||
} else if (!targetId) {
|
||||
// 文件树中的引用数
|
||||
targetId = popoverTargetElement.parentElement.getAttribute("data-node-id");
|
||||
}
|
||||
const postResponse = await fetchSyncPost(url, {id: targetId});
|
||||
ids = postResponse.data.refIDs;
|
||||
defIds = postResponse.data.defIDs;
|
||||
}
|
||||
|
||||
let hasPin = false;
|
||||
window.siyuan.blockPanels.find((item) => {
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "true"
|
||||
&& JSON.stringify(ids) === JSON.stringify(item.nodeIds)) {
|
||||
hasPin = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (!hasPin &&
|
||||
popoverTargetElement.parentElement.style.opacity !== "0.1" // 反向面板图标拖拽时不应该弹层
|
||||
) {
|
||||
window.siyuan.blockPanels.push(new BlockPanel({
|
||||
targetElement: popoverTargetElement,
|
||||
nodeIds: ids,
|
||||
defIds,
|
||||
}));
|
||||
}
|
||||
showPopover()
|
||||
}, 620);
|
||||
});
|
||||
};
|
||||
|
||||
const hidePopover = (event: MouseEvent & { target: HTMLElement }) => {
|
||||
const blockElement = hasClosestByClassName(event.target, "block__popover", true);
|
||||
const maxEditLevels: { [key: string]: number } = {oid: 0};
|
||||
window.siyuan.blockPanels.forEach((item) => {
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "true") {
|
||||
const level = parseInt(item.element.getAttribute("data-level"));
|
||||
const oid = item.element.getAttribute("data-oid");
|
||||
if (maxEditLevels[oid]) {
|
||||
if (level > maxEditLevels[oid]) {
|
||||
maxEditLevels[oid] = level;
|
||||
}
|
||||
} else {
|
||||
maxEditLevels[oid] = level; // 不能为1,否则 pin 住第三层,第二层会消失
|
||||
}
|
||||
}
|
||||
});
|
||||
if (blockElement) {
|
||||
for (let i = 0; i < window.siyuan.blockPanels.length; i++) {
|
||||
const item = window.siyuan.blockPanels[i];
|
||||
if (item.targetElement &&
|
||||
parseInt(item.element.getAttribute("data-level")) > (maxEditLevels[item.element.getAttribute("data-oid")] || 0) &&
|
||||
item.element.getAttribute("data-pin") === "false" &&
|
||||
parseInt(item.element.getAttribute("data-level")) > parseInt(blockElement.getAttribute("data-level"))) {
|
||||
item.destroy();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < window.siyuan.blockPanels.length; i++) {
|
||||
const item = window.siyuan.blockPanels[i];
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "false" &&
|
||||
parseInt(item.element.getAttribute("data-level")) > (maxEditLevels[item.element.getAttribute("data-oid")] || 0)) {
|
||||
item.destroy();
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getTarget = (event: MouseEvent & { target: HTMLElement }, aElement: false | HTMLElement) => {
|
||||
if (hasClosestByClassName(event.target, "history__repo", true)) {
|
||||
return false;
|
||||
}
|
||||
popoverTargetElement = hasClosestByAttribute(event.target, "data-type", "block-ref") as HTMLElement ||
|
||||
hasClosestByAttribute(event.target, "data-type", "virtual-block-ref") as HTMLElement;
|
||||
if (popoverTargetElement && popoverTargetElement.classList.contains("b3-tooltips")) {
|
||||
popoverTargetElement = undefined;
|
||||
}
|
||||
if (!popoverTargetElement) {
|
||||
popoverTargetElement = hasClosestByClassName(event.target, "popover__block") as HTMLElement;
|
||||
}
|
||||
if (!popoverTargetElement && aElement && aElement.getAttribute("data-href")?.startsWith("siyuan://blocks") &&
|
||||
aElement.getAttribute("prevent-popover") !== "true") {
|
||||
popoverTargetElement = aElement;
|
||||
}
|
||||
if (!popoverTargetElement || window.siyuan.altIsPressed || window.siyuan.shiftIsPressed ||
|
||||
(window.siyuan.config.editor.floatWindowMode === 0 && window.siyuan.ctrlIsPressed) ||
|
||||
(popoverTargetElement && popoverTargetElement.getAttribute("prevent-popover") === "true")) {
|
||||
return false;
|
||||
}
|
||||
// https://github.com/siyuan-note/siyuan/issues/4314
|
||||
if (popoverTargetElement && getSelection().rangeCount > 0) {
|
||||
const range = getSelection().getRangeAt(0);
|
||||
if (range.toString() !== "" && popoverTargetElement.contains(range.startContainer)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
export const showPopover = async () => {
|
||||
if (!popoverTargetElement) {
|
||||
return;
|
||||
}
|
||||
let ids: string[];
|
||||
let defIds: string[];
|
||||
const dataId = popoverTargetElement.getAttribute("data-id");
|
||||
if (dataId) {
|
||||
// backlink/util/hint/正文标题 上的弹层
|
||||
if (dataId.startsWith("[")) {
|
||||
ids = JSON.parse(dataId);
|
||||
} else {
|
||||
ids = [dataId];
|
||||
}
|
||||
defIds = JSON.parse(popoverTargetElement.getAttribute("data-defids") || "[]");
|
||||
} else if (popoverTargetElement.getAttribute("data-type")?.indexOf("virtual-block-ref") > -1) {
|
||||
const nodeElement = hasClosestBlock(popoverTargetElement);
|
||||
if (nodeElement) {
|
||||
const postResponse = await fetchSyncPost("/api/block/getBlockDefIDsByRefText", {
|
||||
anchor: popoverTargetElement.textContent,
|
||||
excludeIDs: [nodeElement.getAttribute("data-node-id")]
|
||||
});
|
||||
ids = postResponse.data;
|
||||
}
|
||||
} else if (popoverTargetElement.getAttribute("data-type")?.split(" ").includes("a")) {
|
||||
// 以思源协议开头的链接
|
||||
ids = [popoverTargetElement.getAttribute("data-href").substr(16, 22)];
|
||||
} else {
|
||||
// pdf
|
||||
let targetId;
|
||||
let url = "/api/block/getRefIDs";
|
||||
if (popoverTargetElement.classList.contains("protyle-attr--refcount")) {
|
||||
// 编辑器中的引用数
|
||||
targetId = popoverTargetElement.parentElement.parentElement.getAttribute("data-node-id");
|
||||
} else if (popoverTargetElement.classList.contains("pdf__rect")) {
|
||||
targetId = popoverTargetElement.getAttribute("data-node-id");
|
||||
url = "/api/block/getRefIDsByFileAnnotationID";
|
||||
} else if (!targetId) {
|
||||
// 文件树中的引用数
|
||||
targetId = popoverTargetElement.parentElement.getAttribute("data-node-id");
|
||||
}
|
||||
const postResponse = await fetchSyncPost(url, {id: targetId});
|
||||
ids = postResponse.data.refIDs;
|
||||
defIds = postResponse.data.defIDs;
|
||||
}
|
||||
|
||||
let hasPin = false;
|
||||
window.siyuan.blockPanels.find((item) => {
|
||||
if (item.targetElement && item.element.getAttribute("data-pin") === "true"
|
||||
&& JSON.stringify(ids) === JSON.stringify(item.nodeIds)) {
|
||||
hasPin = true;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
if (!hasPin &&
|
||||
popoverTargetElement.parentElement.style.opacity !== "0.1" // 反向面板图标拖拽时不应该弹层
|
||||
) {
|
||||
window.siyuan.blockPanels.push(new BlockPanel({
|
||||
targetElement: popoverTargetElement,
|
||||
nodeIds: ids,
|
||||
defIds,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import {unicode2Emoji} from "../emoji";
|
|||
import {deleteFile} from "../editor/deleteFile";
|
||||
import {escapeHtml} from "./escape";
|
||||
import {syncGuide} from "../sync/syncGuide";
|
||||
import {showPopover} from "../block/popover";
|
||||
|
||||
const getRightBlock = (element: HTMLElement, x: number, y: number) => {
|
||||
let index = 1;
|
||||
|
|
@ -338,6 +339,9 @@ export const globalShortcut = () => {
|
|||
if (!event.altKey && !event.shiftKey && isCtrl(event)) {
|
||||
if (event.key === "Meta" || event.key === "Control" || event.ctrlKey || event.metaKey) {
|
||||
window.siyuan.ctrlIsPressed = true;
|
||||
if (window.siyuan.config.editor.floatWindowMode === 1) {
|
||||
showPopover()
|
||||
}
|
||||
} else {
|
||||
window.siyuan.ctrlIsPressed = false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue