diff --git a/app/src/editor/util.ts b/app/src/editor/util.ts index a2953a1c6..3e7001ccd 100644 --- a/app/src/editor/util.ts +++ b/app/src/editor/util.ts @@ -547,12 +547,17 @@ export const updateOutline = (models: IModels, protyle: IProtyle, reload = false if (blockId === item.blockId && !reload) { return; } + if (protyle && !protyle.preview.element.classList.contains("fn__none")) { + protyle.preview.render(protyle); + return; + } fetchPost("/api/outline/getDocOutline", { id: blockId, }, response => { - if (!isCurrentEditor(blockId) || item.blockId === blockId) { + if (!reload && (!isCurrentEditor(blockId) || item.blockId === blockId)) { return; } + item.isPreview = false; item.update(response, blockId); if (protyle) { item.updateDocTitle(protyle.background.ial); @@ -569,7 +574,6 @@ export const updateOutline = (models: IModels, protyle: IProtyle, reload = false item.updateDocTitle(); } }); - return; } }); }; diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index 93478640a..2ca5d8850 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -20,6 +20,7 @@ export class Outline extends Model { public headerElement: HTMLElement; public type: "pin" | "local"; public blockId: string; + public isPreview: boolean; private openNodes: { [key: string]: string[] } = {}; constructor(options: { @@ -102,13 +103,17 @@ export class Outline extends Model { data: null, click: (element: HTMLElement) => { const id = element.getAttribute("data-node-id"); - fetchPost("/api/attr/getBlockAttrs", {id}, (attrResponse) => { - openFileById({ - app: options.app, - id, - action: attrResponse.data["heading-fold"] === "1" ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML], + if (this.isPreview) { + document.getElementById(id)?.scrollIntoView() + } else { + fetchPost("/api/attr/getBlockAttrs", {id}, (attrResponse) => { + openFileById({ + app: options.app, + id, + action: attrResponse.data["heading-fold"] === "1" ? [Constants.CB_GET_FOCUS, Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_FOCUS, Constants.CB_GET_SETID, Constants.CB_GET_CONTEXT, Constants.CB_GET_HTML], + }); }); - }); + } } }); // 为了快捷键的 dispatch @@ -200,6 +205,9 @@ export class Outline extends Model { } private onTransaction(data: IWebSocketData) { + if (this.isPreview) { + return; + } let needReload = false; data.data[0].doOperations.forEach((item: IOperation) => { if ((item.action === "update" || item.action === "insert") && @@ -286,18 +294,25 @@ export class Outline extends Model { currentId = currentElement.getAttribute("data-node-id"); } - if (this.openNodes[this.blockId]) { + if (!this.isPreview && this.openNodes[this.blockId]) { this.openNodes[this.blockId] = this.tree.getExpandIds(); } if (typeof callbackId !== "undefined") { this.blockId = callbackId; } this.tree.updateData(data.data); - if (this.openNodes[this.blockId] && !this.headerElement.querySelector('[data-type="expand"]').classList.contains("block__icon--active")) { + if (!this.isPreview && this.openNodes[this.blockId] && !this.headerElement.querySelector('[data-type="expand"]').classList.contains("block__icon--active")) { this.tree.setExpandIds(this.openNodes[this.blockId]); } else { this.tree.expandAll(); - this.openNodes[this.blockId] = this.tree.getExpandIds(); + if (!this.isPreview) { + this.openNodes[this.blockId] = this.tree.getExpandIds(); + } + } + if (this.isPreview) { + this.tree.element.querySelectorAll(".popover__block").forEach(item => { + item.classList.remove("popover__block"); + }) } if (currentId) { diff --git a/app/src/protyle/preview/index.ts b/app/src/protyle/preview/index.ts index 6de8a72e6..15bdb0973 100644 --- a/app/src/protyle/preview/index.ts +++ b/app/src/protyle/preview/index.ts @@ -1,5 +1,4 @@ -import {getEventName, openByMobile, writeText} from "../util/compatibility"; -import {hasClosestByTag} from "../util/hasClosest"; +import {openByMobile, writeText} from "../util/compatibility"; import {focusByRange} from "../util/selection"; import {showMessage} from "../../dialog/message"; import {isLocalPath, pathPosix} from "../../util/pathName"; @@ -19,6 +18,7 @@ import {highlightRender} from "../render/highlightRender"; import {speechRender} from "../render/speechRender"; import {avRender} from "../render/av/render"; import {setPanelFocus} from "../../layout/util"; +import {getAllModels} from "../../layout/getAll"; export class Preview { public element: HTMLElement; @@ -159,11 +159,24 @@ export class Preview { fetchPost("/api/export/preview", { id: protyle.block.parentID || protyle.options.blockId, }, response => { + const oldScrollTop = protyle.preview.previewElement.scrollTop; protyle.preview.previewElement.innerHTML = response.data.html; processRender(protyle.preview.previewElement); highlightRender(protyle.preview.previewElement); avRender(protyle.preview.previewElement); speechRender(protyle.preview.previewElement, protyle.options.lang); + protyle.preview.previewElement.scrollTop = oldScrollTop; + getAllModels().outline.find(item => { + if (item.type === "pin" || (item.type === "local" && item.blockId === protyle.block.rootID)) { + response.data = response.data.outline; + item.isPreview = true; + item.update(response, protyle.block.rootID); + if (item.type === "pin") { + item.updateDocTitle(protyle.background.ial); + } + return; + } + }); }); }, protyle.options.preview.delay); } diff --git a/app/src/protyle/util/setEditMode.ts b/app/src/protyle/util/setEditMode.ts index 879e2241c..e1ad7a739 100644 --- a/app/src/protyle/util/setEditMode.ts +++ b/app/src/protyle/util/setEditMode.ts @@ -1,5 +1,7 @@ import {setPadding} from "../ui/initUI"; import {hideElements} from "../ui/hideElements"; +import {getAllModels} from "../../layout/getAll"; +import {updateOutline} from "../../editor/util"; export const setEditMode = (protyle: IProtyle, type: TEditorMode) => { if (type === "preview") { @@ -29,6 +31,7 @@ export const setEditMode = (protyle: IProtyle, type: TEditorMode) => { protyle.breadcrumb?.element.classList.remove("fn__none"); protyle.breadcrumb.toggleExit(!protyle.block.showAll); } + updateOutline(getAllModels(), protyle, true); } hideElements(["gutter", "toolbar", "select", "hint", "util"], protyle); };