Something went wrong. Try again.
A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675import {Tab} from "../Tab";import {Model} from "../Model";import {Tree} from "../../util/Tree";import {setPanelFocus} from "../util";import {getDockByType} from "../tabUtil";import {fetchPost} from "../../util/fetch";import {Constants} from "../../constants";import {updateHotkeyAfterTip} from "../../protyle/util/compatibility";import {openFileById} from "../../editor/util";import {Protyle} from "../../protyle";import {MenuItem} from "../../menus/Menu";import {App} from "../../index";import {isSupportCSSHL, searchMarkRender} from "../../protyle/render/searchMarkRender";
export class Backlink extends Model { public element: HTMLElement; public inputsElement: NodeListOf<HTMLInputElement>; public type: "pin" | "local"; public blockId: string; public rootId: string; // "local" 必传 public tree: Tree; private notebookId: string; public mTree: Tree; public editors: Protyle[] = []; public status: { [key: string]: { sort: number, mSort: number, scrollTop: number, mScrollTop: number, backlinkOpenIds: string[], backlinkMOpenIds: string[], backlinkMStatus: number // 0 全展开,1 展开一半箭头向下,2 展开一半箭头向上,3 全收起 } } = {};
constructor(options: { app: App, tab: Tab, blockId: string, rootId?: string, type: "pin" | "local" }) { super({ app: options.app, id: options.tab.id, callback() { if (this.type === "local") { fetchPost("/api/block/checkBlockExist", {id: this.blockId}, existResponse => { if (!existResponse.data) { this.parent.parent.removeTab(this.parent.id); } }); } }, msgCallback(data) { if (data && this.type === "local") { switch (data.cmd) { case "rename": if (this.rootId === data.data.id) { this.parent.updateTitle(data.data.title); } break; case "unmount": if (this.notebookId === data.data.box && this.type === "local") { this.parent.parent.removeTab(this.parent.id); } break; case "removeDoc": if (data.data.ids.includes(this.rootId) && this.type === "local") { this.parent.parent.removeTab(this.parent.id); } break; } } } }); this.blockId = options.blockId; this.rootId = options.rootId; this.type = options.type; this.element = options.tab.panelElement; this.element.classList.add("fn__flex-column", "file-tree", "sy__backlink", "dockPanel"); const backlinkSort = window.siyuan.config.editor.backlinkSort; const backmentionSort = window.siyuan.config.editor.backmentionSort; this.element.innerHTML = `<div class="block__icons"> <div class="block__logo"> <svg class="block__logoicon"><use xlink:href="#iconLink"></use></svg>${window.siyuan.languages.backlinks} </div> <span class="counter listCount" style="margin-left: 0"></span> <span class="fn__flex-1"></span> <span class="fn__space"></span> <input class="b3-text-field search__label fn__none fn__size200" placeholder="${window.siyuan.languages.filterKeywordEnter}" /> <span data-type="search" class="block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.filter}"><svg><use xlink:href='#iconFilter'></use></svg></span> <span class="fn__space"></span> <span data-type="refresh" class="block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.refresh}"><svg><use xlink:href='#iconRefresh'></use></svg></span> <span class="fn__space"></span> <span data-type="sort" data-sort="${backlinkSort}" class="block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.sort}"><svg><use xlink:href='#iconSort'></use></svg></span> <span class="fn__space"></span> <span data-type="expand" class="block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.expand}${updateHotkeyAfterTip(window.siyuan.config.keymap.editor.general.expand.custom)}"> <svg><use xlink:href="#iconExpand"></use></svg> </span> <span class="fn__space"></span> <span data-type="collapse" class="block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.collapse}${updateHotkeyAfterTip(window.siyuan.config.keymap.editor.general.collapse.custom)}"> <svg><use xlink:href="#iconContract"></use></svg> </span> <span class="${this.type === "local" ? "fn__none " : ""}fn__space"></span> <span data-type="min" class="${this.type === "local" ? "fn__none " : ""}block__icon b3-tooltips b3-tooltips__sw" aria-label="${window.siyuan.languages.min}${updateHotkeyAfterTip(window.siyuan.config.keymap.general.closeTab.custom)}"><svg><use xlink:href='#iconMin'></use></svg></span></div><div class="backlinkList fn__flex-1"></div><div class="block__icons"> <div class="block__logo"> <svg class="block__logoicon"><use xlink:href="#iconLink"></use></svg>${window.siyuan.languages.mentions} </div> <span class="counter listMCount" style="margin-left: 0;"></span> <span class="fn__flex-1"></span> <span class="fn__space"></span> <input class="b3-text-field search__label fn__none fn__size200" placeholder="${window.siyuan.languages.filterKeywordEnter}" /> <span data-type="search" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.filter}"><svg><use xlink:href='#iconFilter'></use></svg></span> <span class="fn__space"></span> <span data-type="mSort" data-sort="${backmentionSort}" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.sort}"><svg><use xlink:href='#iconSort'></use></svg></span> <span class="fn__space"></span> <span data-type="mExpand" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.expand}"> <svg><use xlink:href="#iconExpand"></use></svg> </span> <span class="fn__space"></span> <span data-type="mCollapse" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.collapse}"> <svg><use xlink:href="#iconContract"></use></svg> </span> <span class="fn__space"></span> <span data-type="layout" class="block__icon b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.down}"> <svg><use xlink:href="#iconDown"></use></svg> </span></div><div class="backlinkMList fn__flex-1"></div>`;
this.inputsElement = this.element.querySelectorAll("input"); this.inputsElement.forEach((item) => { item.addEventListener("blur", (event: KeyboardEvent) => { const inputElement = event.target as HTMLInputElement; inputElement.classList.add("fn__none"); const filterIconElement = inputElement.nextElementSibling; if (inputElement.value) { filterIconElement.classList.add("block__icon--active"); filterIconElement.setAttribute("aria-label", window.siyuan.languages.filter + " " + inputElement.value); } else { filterIconElement.classList.remove("block__icon--active"); filterIconElement.setAttribute("aria-label", window.siyuan.languages.filter); } }); item.addEventListener("keydown", (event: KeyboardEvent) => { if (!event.isComposing && event.key === "Enter") { this.searchBacklinks(); } }); }); this.tree = new Tree({ element: this.element.querySelector(".backlinkList") as HTMLElement, data: null, click: (element) => { this.toggleItem(element, false); this.setFocus(); this.mTree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, ctrlClick: (element) => { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), action: [Constants.CB_GET_CONTEXT] }); this.mTree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, altClick(element) { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), position: "right", action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] }); this.mTree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, shiftClick(element) { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), position: "bottom", action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] }); this.mTree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, toggleClick: (liElement) => { this.toggleItem(liElement, false); this.setFocus(); this.mTree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); } }); this.mTree = new Tree({ element: this.element.querySelector(".backlinkMList") as HTMLElement, data: null, click: (element) => { this.toggleItem(element, true); this.setFocus(); this.tree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, ctrlClick(element) { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), action: [Constants.CB_GET_CONTEXT] }); this.tree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, altClick(element) { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), position: "right", action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] }); this.tree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, shiftClick(element) { openFileById({ app: options.app, id: element.getAttribute("data-node-id"), position: "bottom", action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] }); this.tree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, toggleClick: (liElement) => { this.toggleItem(liElement, true); this.setFocus(); this.tree.element.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); }, blockExtHTML: `<span class="b3-list-item__action b3-tooltips b3-tooltips__nw" aria-label="${window.siyuan.languages.more}"><svg><use xlink:href="#iconMore"></use></svg></span>` }); this.tree.element.addEventListener("scroll", () => { this.tree.element.querySelectorAll(".protyle-gutters").forEach(item => { item.classList.add("fn__none"); item.innerHTML = ""; }); this.tree.element.querySelectorAll(".protyle-wysiwyg--hl").forEach((hlItem) => { hlItem.classList.remove("protyle-wysiwyg--hl"); }); }); this.mTree.element.addEventListener("scroll", () => { this.mTree.element.querySelectorAll(".protyle-gutters").forEach(item => { item.classList.add("fn__none"); item.innerHTML = ""; }); this.mTree.element.querySelectorAll(".protyle-wysiwyg--hl").forEach((hlItem) => { hlItem.classList.remove("protyle-wysiwyg--hl"); }); }); // 为了快捷键的 dispatch this.element.querySelector('[data-type="collapse"]').addEventListener("click", () => { this.tree.element.querySelectorAll(".protyle").forEach(item => { item.classList.add("fn__none"); }); this.tree.element.querySelectorAll(".b3-list-item__arrow").forEach(item => { item.classList.remove("b3-list-item__arrow--open"); }); }); this.element.querySelector('[data-type="expand"]').addEventListener("click", () => { Array.from(this.tree.element.firstElementChild.children).forEach((item: HTMLElement) => { if (item.tagName === "LI" && !item.querySelector(".b3-list-item__arrow--open")) { this.toggleItem(item, false); } }); }); this.element.addEventListener("click", (event) => { this.setFocus(); let target = event.target as HTMLElement; while (target && !target.isEqualNode(this.element)) { if (target.classList.contains("block__icon") && target.parentElement.parentElement === this.element) { const type = target.getAttribute("data-type"); switch (type) { case "refresh": this.refresh(); break; case "mExpand": Array.from(this.mTree.element.firstElementChild.children).forEach((item: HTMLElement) => { if (item.tagName === "LI" && !item.querySelector(".b3-list-item__arrow--open")) { this.toggleItem(item, true); } }); break; case "mCollapse": this.mTree.element.querySelectorAll(".protyle").forEach(item => { item.classList.add("fn__none"); }); this.mTree.element.querySelectorAll(".b3-list-item__arrow").forEach(item => { item.classList.remove("b3-list-item__arrow--open"); }); break; case "min": getDockByType("backlink").toggleModel("backlink", false, true); break; case "search": target.previousElementSibling.classList.remove("fn__none"); (target.previousElementSibling as HTMLInputElement).select(); break; case "sort": case "mSort": this.showSortMenu(type, target.getAttribute("data-sort")); window.siyuan.menus.menu.popup({x: event.clientX, y: event.clientY}); event.stopPropagation(); break; case "layout": if (this.mTree.element.style.flex) { if (this.mTree.element.style.height === "0px") { this.tree.element.classList.remove("fn__none"); this.mTree.element.removeAttribute("style"); target.setAttribute("aria-label", window.siyuan.languages.up); target.querySelector("use").setAttribute("xlink:href", "#iconUp"); } else { this.tree.element.classList.remove("fn__none"); this.mTree.element.removeAttribute("style"); target.setAttribute("aria-label", window.siyuan.languages.down); target.querySelector("use").setAttribute("xlink:href", "#iconDown"); } } else { if (target.getAttribute("aria-label") === window.siyuan.languages.down) { this.tree.element.classList.remove("fn__none"); this.mTree.element.setAttribute("style", "flex:none;height:0px"); target.setAttribute("aria-label", window.siyuan.languages.up); target.querySelector("use").setAttribute("xlink:href", "#iconUp"); } else { this.tree.element.classList.add("fn__none"); this.mTree.element.setAttribute("style", `flex:none;height:${this.element.clientHeight - this.tree.element.previousElementSibling.clientHeight * 2}px`); target.setAttribute("aria-label", window.siyuan.languages.down); target.querySelector("use").setAttribute("xlink:href", "#iconDown"); } } this.tree.element.dispatchEvent(new CustomEvent("scroll")); this.mTree.element.dispatchEvent(new CustomEvent("scroll")); break; } } target = target.parentElement; } });
this.searchBacklinks(true); }
private setFocus() { if (this.type === "local") { setPanelFocus(this.element.parentElement.parentElement); } else { setPanelFocus(this.element); } }
private showSortMenu(type: string, sort: string) { const clickEvent = (currentSort: string) => { (type === "sort" ? this.tree : this.mTree).element.previousElementSibling.querySelector(`[data-type="${type}"]`).setAttribute("data-sort", currentSort); // 保存排序状态到配置 const sortValue = parseInt(currentSort); if (type === "sort") { window.siyuan.config.editor.backlinkSort = sortValue; } else { window.siyuan.config.editor.backmentionSort = sortValue; } fetchPost("/api/setting/setEditor", window.siyuan.config.editor); this.searchBacklinks(); }; window.siyuan.menus.menu.remove(); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "0" ? "iconSelect" : undefined, label: window.siyuan.languages.fileNameASC, click: () => { clickEvent("0"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "1" ? "iconSelect" : undefined, label: window.siyuan.languages.fileNameDESC, click: () => { clickEvent("1"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "4" ? "iconSelect" : undefined, label: window.siyuan.languages.fileNameNatASC, click: () => { clickEvent("4"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "5" ? "iconSelect" : undefined, label: window.siyuan.languages.fileNameNatDESC, click: () => { clickEvent("5"); } }).element); window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "9" ? "iconSelect" : undefined, label: window.siyuan.languages.createdASC, click: () => { clickEvent("9"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "10" ? "iconSelect" : undefined, label: window.siyuan.languages.createdDESC, click: () => { clickEvent("10"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "2" ? "iconSelect" : undefined, label: window.siyuan.languages.modifiedASC, click: () => { clickEvent("2"); } }).element); window.siyuan.menus.menu.append(new MenuItem({ icon: sort === "3" ? "iconSelect" : undefined, label: window.siyuan.languages.modifiedDESC, click: () => { clickEvent("3"); } }).element); }
private toggleItem(liElement: HTMLElement, isMention: boolean) { const svgElement = liElement.firstElementChild?.firstElementChild; if (!svgElement || svgElement.getAttribute("disabled")) { return; } svgElement.setAttribute("disabled", "disabled"); const docId = liElement.getAttribute("data-node-id"); if (svgElement.classList.contains("b3-list-item__arrow--open")) { svgElement.classList.remove("b3-list-item__arrow--open"); this.editors.find((item, index) => { if (item.protyle.block.rootID === docId && liElement.nextElementSibling && item.protyle.element === liElement.nextElementSibling) { item.destroy(); this.editors.splice(index, 1); liElement.nextElementSibling.remove(); return true; } }); svgElement.removeAttribute("disabled"); } else { const keyword = isMention ? this.inputsElement[1].value : this.inputsElement[0].value; fetchPost(isMention ? "/api/ref/getBackmentionDoc" : "/api/ref/getBacklinkDoc", { defID: this.blockId, refTreeID: docId, highlight: !isSupportCSSHL(), keyword, }, (response) => { svgElement.removeAttribute("disabled"); svgElement.classList.add("b3-list-item__arrow--open"); const editorElement = document.createElement("div"); editorElement.style.minHeight = "auto"; editorElement.setAttribute("data-defid", this.blockId); editorElement.setAttribute("data-ismention", isMention ? "true" : "false"); liElement.after(editorElement); const editor = new Protyle(this.app, editorElement, { blockId: docId, click: { preventInsetEmptyBlock: true }, backlinkData: isMention ? response.data.backmentions : response.data.backlinks, render: { background: false, gutter: true, scroll: false, breadcrumb: false, } }); editor.protyle.notebookId = liElement.getAttribute("data-notebook-id"); searchMarkRender(editor.protyle, response.data.keywords); this.editors.push(editor); }); } }
public refresh() { const element = this.element.querySelector('.block__icon[data-type="refresh"] svg'); if (!this.blockId || element.classList.contains("fn__rotate")) { return; } element.classList.add("fn__rotate"); fetchPost("/api/ref/refreshBacklink", { id: this.blockId, }, () => { element.classList.remove("fn__rotate"); this.searchBacklinks(); }); }
private searchBacklinks(init = false) { const element = this.element.querySelector('.block__icon[data-type="refresh"] svg'); if (element.classList.contains("fn__rotate")) { return; } element.classList.add("fn__rotate"); fetchPost("/api/ref/getBacklink2", { sort: parseInt(this.tree.element.previousElementSibling.querySelector('[data-type="sort"]').getAttribute("data-sort")).toString(), mSort: parseInt(this.mTree.element.previousElementSibling.querySelector('[data-type="mSort"]').getAttribute("data-sort")).toString(), k: this.inputsElement[0].value, mk: this.inputsElement[1].value, id: this.blockId, }, response => { if (!init) { this.saveStatus(); } this.render(response.data); }); }
public saveStatus() { this.status[this.blockId] = { sort: parseInt(this.tree.element.previousElementSibling.querySelector('[data-type="sort"]').getAttribute("data-sort")), mSort: parseInt(this.mTree.element.previousElementSibling.querySelector('[data-type="mSort"]').getAttribute("data-sort")), scrollTop: this.tree.element.scrollTop, mScrollTop: this.mTree.element.scrollTop, backlinkOpenIds: [], backlinkMOpenIds: [], backlinkMStatus: 3 // 0 全展开,1 展开一半箭头向下,2 展开一半箭头向上,3 全收起 }; this.tree.element.querySelectorAll(".b3-list-item__arrow--open").forEach(item => { this.status[this.blockId].backlinkOpenIds.push(item.parentElement.parentElement.getAttribute("data-node-id")); }); this.mTree.element.querySelectorAll(".b3-list-item__arrow--open").forEach(item => { this.status[this.blockId].backlinkMOpenIds.push(item.parentElement.parentElement.getAttribute("data-node-id")); }); if (this.mTree.element.style.flex) { if (this.mTree.element.style.height === "0px") { this.status[this.blockId].backlinkMStatus = 3; } else { this.status[this.blockId].backlinkMStatus = 0; } } else { if (this.mTree.element.previousElementSibling.querySelector('[data-type="layout"]').getAttribute("aria-label") === window.siyuan.languages.down) { this.status[this.blockId].backlinkMStatus = 1; } else { this.status[this.blockId].backlinkMStatus = 2; } } }
public render(data: { box: string, backlinks: IBlockTree[], backmentions: IBlockTree[], linkRefsCount: number, mentionsCount: number, k: string, mk: string }) { if (!data) { data = { box: "", backlinks: [], backmentions: [], linkRefsCount: 0, mentionsCount: 0, k: "", mk: "" }; }
this.editors.forEach(item => { item.destroy(); }); this.editors = []; this.element.querySelector('.block__icon[data-type="refresh"] svg').classList.remove("fn__rotate"); this.notebookId = data.box; this.inputsElement[0].value = data.k; this.inputsElement[1].value = data.mk; this.tree.updateData(data.backlinks); this.mTree.updateData(data.backmentions);
const countElement = this.element.querySelector(".listCount"); if (data.linkRefsCount === 0) { countElement.classList.add("fn__none"); } else { countElement.classList.remove("fn__none"); countElement.textContent = data.linkRefsCount.toString(); } const mCountElement = this.element.querySelector(".listMCount"); if (data.mentionsCount === 0) { mCountElement.classList.add("fn__none"); } else { mCountElement.classList.remove("fn__none"); mCountElement.textContent = data.mentionsCount.toString(); }
if (!this.status[this.blockId]) { this.status[this.blockId] = { sort: window.siyuan.config.editor.backlinkSort, mSort: window.siyuan.config.editor.backmentionSort, scrollTop: 0, mScrollTop: 0, backlinkOpenIds: [], backlinkMOpenIds: [], backlinkMStatus: 3 }; if (data.mentionsCount === 0 || window.siyuan.config.editor.backmentionExpandCount === -1) { this.status[this.blockId].backlinkMStatus = 3; } else { Array.from({length: window.siyuan.config.editor.backmentionExpandCount}).forEach((item, index) => { if (data.backmentions[index]) { this.status[this.blockId].backlinkMOpenIds.push(data.backmentions[index].id); } }); if (data.mentionsCount === 0) { this.status[this.blockId].backlinkMStatus = 3; } else { if (data.linkRefsCount === 0) { this.status[this.blockId].backlinkMStatus = 0; } else { this.status[this.blockId].backlinkMStatus = 1; } } } if (data.linkRefsCount > 0) { Array.from({length: window.siyuan.config.editor.backlinkExpandCount}).forEach((item, index) => { if (data.backlinks[index]) { this.status[this.blockId].backlinkOpenIds.push(data.backlinks[index].id); } }); } }
// restore status this.status[this.blockId].backlinkOpenIds.forEach(item => { const liElement = this.tree.element.querySelector(`.b3-list-item[data-node-id="${item}"]`) as HTMLElement; if (liElement) { this.toggleItem(liElement, false); } }); this.status[this.blockId].backlinkMOpenIds.forEach(item => { const liElement = this.mTree.element.querySelector(`.b3-list-item[data-node-id="${item}"]`) as HTMLElement; if (liElement) { this.toggleItem(liElement, true); } }); // 0 全展开,1 展开一半箭头向下,2 展开一半箭头向上,3 全收起 const layoutElement = this.mTree.element.previousElementSibling.querySelector('[data-type="layout"]'); if (this.status[this.blockId].backlinkMStatus === 2 || this.status[this.blockId].backlinkMStatus === 1) { this.tree.element.classList.remove("fn__none"); this.mTree.element.removeAttribute("style"); if (this.status[this.blockId].backlinkMStatus === 1) { layoutElement.setAttribute("aria-label", window.siyuan.languages.down); layoutElement.querySelector("use").setAttribute("xlink:href", "#iconDown"); } else { layoutElement.setAttribute("aria-label", window.siyuan.languages.up); layoutElement.querySelector("use").setAttribute("xlink:href", "#iconUp"); } } else if (this.status[this.blockId].backlinkMStatus === 3) { this.tree.element.classList.remove("fn__none"); this.mTree.element.setAttribute("style", "flex:none;height:0px"); layoutElement.setAttribute("aria-label", window.siyuan.languages.up); layoutElement.querySelector("use").setAttribute("xlink:href", "#iconUp"); } else { this.tree.element.classList.add("fn__none"); this.mTree.element.setAttribute("style", `flex:none;height:${this.element.clientHeight - this.tree.element.previousElementSibling.clientHeight * 2}px`); layoutElement.setAttribute("aria-label", window.siyuan.languages.down); layoutElement.querySelector("use").setAttribute("xlink:href", "#iconDown"); } this.tree.element.previousElementSibling.querySelector('[data-type="sort"]').setAttribute("data-sort", this.status[this.blockId].sort.toString()); this.mTree.element.previousElementSibling.querySelector('[data-type="mSort"]').setAttribute("data-sort", this.status[this.blockId].mSort.toString());
setTimeout(() => { this.tree.element.scrollTop = this.status[this.blockId].scrollTop; this.mTree.element.scrollTop = this.status[this.blockId].mScrollTop; }, Constants.TIMEOUT_LOAD); }}