81 lines
2.9 KiB
JavaScript
81 lines
2.9 KiB
JavaScript
|
|
// ========================================
|
|||
|
|
// 模块:鼠标中键折叠/展开功能
|
|||
|
|
// ========================================
|
|||
|
|
|
|||
|
|
// 查找可编辑父元素的工具函数
|
|||
|
|
const findEditableParent = (node) => {
|
|||
|
|
return node.closest('[contenteditable="true"], .protyle-wysiwyg');
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 初始化鼠标中键折叠/展开功能
|
|||
|
|
export const initMiddleClickCollapse = () => {
|
|||
|
|
// 在初始化之前先清理之前的实例
|
|||
|
|
if (window.theme && window.theme._collapseHandler) {
|
|||
|
|
cleanupMiddleClickCollapse();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const DEBOUNCE_TIME = 300;
|
|||
|
|
let lastClickTime = 0;
|
|||
|
|
|
|||
|
|
const collapseHandler = (e) => {
|
|||
|
|
if (e.button !== 1 || e.shiftKey || e.altKey || Date.now() - lastClickTime < DEBOUNCE_TIME) return;
|
|||
|
|
lastClickTime = Date.now();
|
|||
|
|
|
|||
|
|
// 查找可编辑块和目标元素
|
|||
|
|
const editable = findEditableParent(e.target);
|
|||
|
|
if (!editable) return;
|
|||
|
|
|
|||
|
|
const found = editable.closest('[data-type="NodeListItem"], [data-type="NodeHeading"]');
|
|||
|
|
if (!found) return;
|
|||
|
|
|
|||
|
|
e.preventDefault();
|
|||
|
|
|
|||
|
|
// 处理列表项或标题的折叠/展开
|
|||
|
|
const dataType = found.getAttribute("data-type");
|
|||
|
|
if (dataType === "NodeListItem") {
|
|||
|
|
const nodeId = found.getAttribute("data-node-id");
|
|||
|
|
if (!nodeId || !found.querySelector(':scope > .list')) return;
|
|||
|
|
|
|||
|
|
const fold = found.getAttribute("fold");
|
|||
|
|
const newFold = fold === "1" ? "0" : "1";
|
|||
|
|
|
|||
|
|
// 直接发送API请求设置折叠状态
|
|||
|
|
fetch('/api/attr/setBlockAttrs', {
|
|||
|
|
method: 'POST',
|
|||
|
|
headers: {
|
|||
|
|
'Content-Type': 'application/json',
|
|||
|
|
'Authorization': `Token ${window.siyuan?.config?.api?.token ?? ""}`
|
|||
|
|
},
|
|||
|
|
body: JSON.stringify({
|
|||
|
|
id: nodeId,
|
|||
|
|
attrs: { fold: newFold }
|
|||
|
|
})
|
|||
|
|
}).then(() => {
|
|||
|
|
found.setAttribute('fold', newFold);
|
|||
|
|
});
|
|||
|
|
} else if (dataType === "NodeHeading") {
|
|||
|
|
// 查找并点击同级的折叠按钮
|
|||
|
|
const foldBtn = found.closest(".protyle")
|
|||
|
|
?.querySelector(".protyle-gutters")
|
|||
|
|
?.querySelector('[data-type="fold"]');
|
|||
|
|
foldBtn?.click();
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
if (!window.theme) {
|
|||
|
|
window.theme = {};
|
|||
|
|
}
|
|||
|
|
window.theme._collapseHandler = collapseHandler;
|
|||
|
|
document.body.addEventListener("mousedown", collapseHandler);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 添加清理函数
|
|||
|
|
export const cleanupMiddleClickCollapse = () => {
|
|||
|
|
if (window.theme && window.theme._collapseHandler) {
|
|||
|
|
document.body.removeEventListener("mousedown", window.theme._collapseHandler);
|
|||
|
|
window.theme._collapseHandler = null;
|
|||
|
|
}
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 将清理函数也添加到window对象上,以便在destroyTheme中正确调用
|
|||
|
|
window.cleanupMiddleClickCollapse = cleanupMiddleClickCollapse;
|