From 8b8859bc54b6dc94428a0873a0d6d6109d53113f Mon Sep 17 00:00:00 2001 From: Vanessa Date: Sun, 2 Oct 2022 20:15:08 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20https://github.com/siyuan-note/siy?= =?UTF-8?q?uan/issues/3565=20=E6=8A=98=E5=8F=A0=E7=A7=BB=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/layout/dock/Backlink.ts | 53 ++-- app/src/layout/dock/Backlinks.ts | 422 ------------------------------- 2 files changed, 29 insertions(+), 446 deletions(-) delete mode 100644 app/src/layout/dock/Backlinks.ts diff --git a/app/src/layout/dock/Backlink.ts b/app/src/layout/dock/Backlink.ts index ab84514ff..3d62be607 100644 --- a/app/src/layout/dock/Backlink.ts +++ b/app/src/layout/dock/Backlink.ts @@ -287,35 +287,40 @@ export class Backlink extends Model { private toggleItem(liElement: HTMLElement, isMention: boolean) { const svgElement = liElement.firstElementChild.firstElementChild; + const docId = liElement.getAttribute("data-node-id") if (svgElement.classList.contains("b3-list-item__arrow--open")) { svgElement.classList.remove("b3-list-item__arrow--open"); - liElement.nextElementSibling?.classList.add("fn__none"); + this.editors.find((item, index) => { + if (item.protyle.block.rootID === docId) { + item.destroy(); + this.editors.splice(index, 1); + return true; + } + }); + liElement.nextElementSibling?.remove(); } else { svgElement.classList.add("b3-list-item__arrow--open"); - if (liElement.nextElementSibling && liElement.nextElementSibling.tagName === "DIV") { - liElement.nextElementSibling.classList.remove("fn__none"); - } else { - fetchPost(isMention ? "/api/ref/getBackmentionDoc" : "/api/ref/getBacklinkDoc", { - defID: this.blockId, - refTreeID: liElement.getAttribute("data-node-id") - }, (response) => { - const editorElement = document.createElement("div"); - editorElement.style.minHeight = "auto"; - liElement.after(editorElement); - const editor = new Protyle(editorElement, { - blockId: "", - backlinkData: isMention ? response.data.backmentions : response.data.backlinks, - render: { - background: false, - title: false, - gutter: true, - scroll: false, - breadcrumb: false, - } - }); - this.editors.push(editor); + fetchPost(isMention ? "/api/ref/getBackmentionDoc" : "/api/ref/getBacklinkDoc", { + defID: this.blockId, + refTreeID: docId + }, (response) => { + const editorElement = document.createElement("div"); + editorElement.style.minHeight = "auto"; + liElement.after(editorElement); + const editor = new Protyle(editorElement, { + blockId: "", + backlinkData: isMention ? response.data.backmentions : response.data.backlinks, + render: { + background: false, + title: false, + gutter: true, + scroll: false, + breadcrumb: false, + } }); - } + editor.protyle.block.rootID = docId + this.editors.push(editor); + }); } } diff --git a/app/src/layout/dock/Backlinks.ts b/app/src/layout/dock/Backlinks.ts deleted file mode 100644 index a315fcbe1..000000000 --- a/app/src/layout/dock/Backlinks.ts +++ /dev/null @@ -1,422 +0,0 @@ -import {Tab} from "../Tab"; -import {Model} from "../Model"; -import {getDisplayName} from "../../util/pathName"; -import {Tree} from "../../util/Tree"; -import {hasClosestByClassName} from "../../protyle/util/hasClosest"; -import {getDockByType, setPanelFocus} from "../util"; -import {fetchPost} from "../../util/fetch"; -import {Constants} from "../../constants"; -import {getAllModels} from "../getAll"; -import {onGet} from "../../protyle/util/onGet"; -import {updateHotkeyTip} from "../../protyle/util/compatibility"; -import {openFileById} from "../../editor/util"; -import {MenuItem} from "../../menus/Menu"; - -export class Backlinks extends Model { - public element: HTMLElement; - public inputsElement: NodeListOf; - public type: "pin" | "local"; - public blockId: string; - public rootId: string; // "local" 必传 - private tree: Tree; - private notebookId: string; - private mTree: Tree; - public beforeLen = 10; - - constructor(options: { - tab: Tab, - blockId: string, - rootId?: string, - type: "pin" | "local" - }) { - super({ - 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) { - switch (data.cmd) { - case "rename": - if (this.type === "local" && this.blockId === 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 "remove": - if (this.path?.indexOf(getDisplayName(data.data.path, false, true)) === 0 && 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"); - this.element.innerHTML = `
- - - - - - - - - - - - - - - - - - - - -
- -
- - - - - - - - - - - - - - - - -
-
`; - - this.inputsElement = this.element.querySelectorAll("input"); - this.inputsElement.forEach((item) => { - item.addEventListener("keydown", (event: KeyboardEvent) => { - if (!event.isComposing && event.key === "Enter") { - this.searchBacklinks(); - } - }); - item.addEventListener("input", (event: KeyboardEvent) => { - const inputElement = event.target as HTMLInputElement; - if (inputElement.value === "") { - inputElement.classList.remove("search__input--block"); - } else { - inputElement.classList.add("search__input--block"); - } - }); - }); - - this.tree = new Tree({ - element: this.element.querySelector(".backlinkList") as HTMLElement, - data: null, - click(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - }, - ctrlClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - keepCursor: true, - action: [Constants.CB_GET_CONTEXT] - }); - }, - altClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - position: "right", - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - }, - shiftClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - position: "bottom", - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - } - }); - this.mTree = new Tree({ - element: this.element.querySelector(".backlinkMList") as HTMLElement, - data: null, - click: (element, event) => { - const actionElement = hasClosestByClassName(event.target as HTMLElement, "b3-list-item__action"); - if (actionElement) { - if (actionElement.firstElementChild.classList.contains("fn__rotate")) { - return; - } - window.siyuan.menus.menu.remove(); - window.siyuan.menus.menu.append(new MenuItem({ - label: window.siyuan.languages.turnInto + " " + window.siyuan.languages.turnToStaticRef, - click: () => { - this.turnToRef(element, false); - } - }).element); - window.siyuan.menus.menu.append(new MenuItem({ - label: window.siyuan.languages.turnInto + " " + window.siyuan.languages.turnToDynamicRef, - click: () => { - this.turnToRef(element, true); - } - }).element); - window.siyuan.menus.menu.popup({x: event.clientX, y: event.clientY}); - } else { - openFileById({ - id: element.getAttribute("data-node-id"), - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - } - }, - ctrlClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - keepCursor: true, - action: [Constants.CB_GET_CONTEXT] - }); - }, - altClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - position: "right", - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - }, - shiftClick(element: HTMLElement) { - openFileById({ - id: element.getAttribute("data-node-id"), - position: "bottom", - action: [Constants.CB_GET_FOCUS, Constants.CB_GET_CONTEXT] - }); - }, - blockExtHTML: `` - }); - // 为了快捷键的 dispatch - this.element.querySelector('[data-type="collapse"]').addEventListener("click", () => { - this.tree.collapseAll(); - }); - this.element.querySelector('[data-type="expand"]').addEventListener("click", () => { - this.tree.expandAll(); - }); - this.element.addEventListener("click", (event) => { - if (this.type === "local") { - setPanelFocus(this.element.parentElement.parentElement); - } else { - setPanelFocus(this.element.firstElementChild); - } - let target = event.target as HTMLElement; - while (target && !target.isEqualNode(this.element)) { - if (target.classList.contains("block__icon")) { - const type = target.getAttribute("data-type"); - switch (type) { - case "refresh": - this.refresh(); - break; - case "mExpand": - this.mTree.expandAll(); - break; - case "mCollapse": - this.mTree.collapseAll(); - break; - case "min": - getDockByType("backlink").toggleModel("backlink"); - break; - case "more": - if (target.classList.contains("ft__primary")) { - this.searchBacklinks(this.beforeLen); - target.classList.remove("ft__primary"); - target.parentElement.nextElementSibling.classList.remove("backlink--more"); - } else { - this.searchBacklinks(this.beforeLen * 20); - target.classList.add("ft__primary"); - target.parentElement.nextElementSibling.classList.add("backlink--more"); - } - 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"); - } - } - target.setAttribute("data-clicked", "true"); - break; - } - } - target = target.parentElement; - } - }); - - this.searchBacklinks(); - - if (this.type === "pin") { - setPanelFocus(this.element.firstElementChild); - } - } - - private turnToRef(element: HTMLElement, isDynamic: boolean) { - element.querySelector(".b3-list-item__action").innerHTML = ''; - this.element.querySelector('.block__icon[data-type="refresh"] svg').classList.add("fn__rotate"); - fetchPost("/api/ref/createBacklink", { - refID: element.getAttribute("data-node-id"), - refText: decodeURIComponent(element.getAttribute("data-ref-text")), - defID: this.blockId, - pushMode: 0, - isDynamic - }, response => { - if (response.data.defID === this.blockId) { - this.searchBacklinks(undefined, true); - } - getAllModels().editor.forEach(item => { - if (response.data.refRootID === item.editor.protyle.block.rootID) { - fetchPost("/api/filetree/getDoc", { - id: item.editor.protyle.block.id, - size: Constants.SIZE_GET, - }, getResponse => { - onGet(getResponse, item.editor.protyle); - }); - } - }); - }); - } - - public refresh() { - fetchPost("/api/ref/refreshBacklink", { - id: this.blockId, - }, () => { - this.searchBacklinks(); - }); - } - - private searchBacklinks(beforeLength?: number, ignoreClass = false) { - const element = this.element.querySelector('.block__icon[data-type="refresh"] svg'); - if (element.classList.contains("fn__rotate") && !ignoreClass) { - return; - } - element.classList.add("fn__rotate"); - let beforeLen; - if (beforeLength) { - beforeLen = beforeLength; - } else { - beforeLen = this.element.querySelector('.block__icon[data-type="more"]').classList.contains("ft__primary") ? this.beforeLen * 20 : this.beforeLen; - } - fetchPost("/api/ref/getBacklink", { - k: this.inputsElement[0].value, - mk: this.inputsElement[1].value, - beforeLen, - id: this.blockId, - }, response => { - this.render(response.data); - }); - } - - 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.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(); - } - - const layoutElement = this.element.querySelector("[data-type='layout']"); - if (layoutElement.getAttribute("data-clicked")) { - return; - } - if (data.mentionsCount === 0) { - 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"); - return; - } - if (data.linkRefsCount === 0) { - 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"); - } else { - this.tree.element.classList.remove("fn__none"); - this.mTree.element.removeAttribute("style"); - layoutElement.setAttribute("aria-label", window.siyuan.languages.down); - layoutElement.querySelector("use").setAttribute("xlink:href", "#iconDown"); - } - } -}