diff --git a/app/src/boot/onGetConfig.ts b/app/src/boot/onGetConfig.ts index 627f0a139..2e989b3e8 100644 --- a/app/src/boot/onGetConfig.ts +++ b/app/src/boot/onGetConfig.ts @@ -29,6 +29,7 @@ import {sendGlobalShortcut} from "./globalEvent/keydown"; import {closeWindow} from "../window/closeWin"; import {checkFold} from "../util/noRelyPCFunction"; import {correctHotkey} from "./globalEvent/commonHotkey"; +import {recordBeforeResizeTop} from "../protyle/util/resize"; export const onGetConfig = (isStart: boolean, app: App) => { correctHotkey(app); @@ -67,12 +68,18 @@ export const onGetConfig = (isStart: boolean, app: App) => { setInlineStyle(); renderSnippet(); let resizeTimeout = 0; + let firstResize = true; window.addEventListener("resize", () => { + if (firstResize) { + recordBeforeResizeTop(); + firstResize = false; + } window.clearTimeout(resizeTimeout); resizeTimeout = window.setTimeout(() => { adjustLayout(); resizeTabs(); resizeTopBar(); + firstResize = true; }, 200); }); addGA(); diff --git a/app/src/editor/util.ts b/app/src/editor/util.ts index a0f5c89c4..1ff7da24d 100644 --- a/app/src/editor/util.ts +++ b/app/src/editor/util.ts @@ -386,7 +386,6 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod if (nodeElement) { const newRange = focusBlock(nodeElement); if (newRange) { - // 需要更新 range,否则文档大纲点击导致切换页签时因为 resize 中 `保持光标位置不变` 会导致光标跳动 editor.editor.protyle.toolbar.range = newRange; } scrollCenter(editor.editor.protyle, nodeElement, true); diff --git a/app/src/layout/Wnd.ts b/app/src/layout/Wnd.ts index 2aad0f59b..8f451af8e 100644 --- a/app/src/layout/Wnd.ts +++ b/app/src/layout/Wnd.ts @@ -50,6 +50,7 @@ import {fullscreen} from "../protyle/breadcrumb/action"; import {setPadding} from "../protyle/ui/initUI"; import {setPosition} from "../util/setPosition"; import {clearOBG} from "./dock/util"; +import {recordBeforeResizeTop} from "../protyle/util/resize"; export class Wnd { private app: App; @@ -722,6 +723,7 @@ export class Wnd { if (["bottom", "left", "right"].includes(this.parent.type)) { item.panelElement.remove(); } else { + recordBeforeResizeTop(); this.remove(); } // 关闭分屏页签后光标消失 diff --git a/app/src/layout/dock/index.ts b/app/src/layout/dock/index.ts index 53f8bfc61..af83960e8 100644 --- a/app/src/layout/dock/index.ts +++ b/app/src/layout/dock/index.ts @@ -19,6 +19,7 @@ import {hasClosestByClassName} from "../../protyle/util/hasClosest"; import {App} from "../../index"; import {Plugin} from "../../plugin"; import {Custom} from "./Custom"; +import {recordBeforeResizeTop} from "../../protyle/util/resize"; const TYPES = ["file", "outline", "inbox", "bookmark", "tag", "graph", "globalGraph", "backlink"]; @@ -495,6 +496,7 @@ export class Dock { if (!type) { return; } + recordBeforeResizeTop(); const target = this.element.querySelector(`[data-type="${type}"]`) as HTMLElement; if (show && target.classList.contains("dock__item--active")) { target.classList.remove("dock__item--active", "dock__item--activefocus"); @@ -547,7 +549,7 @@ export class Dock { if (currentElement) { getAllTabs().find(item => { if (item.id === currentElement.getAttribute("data-id")) { - item.parent.switchTab(item.headElement); + item.parent.switchTab(item.headElement, false, true, false); return true; } }); diff --git a/app/src/layout/index.ts b/app/src/layout/index.ts index ee2dd74fb..91e3050dc 100644 --- a/app/src/layout/index.ts +++ b/app/src/layout/index.ts @@ -2,6 +2,7 @@ import {Wnd} from "./Wnd"; import {genUUID} from "../util/genID"; import {addResize, fixWndFlex1} from "./util"; import {resizeTabs} from "./tabUtil"; +import {recordBeforeResizeTop} from "../protyle/util/resize"; /// #if MOBILE // 检测移动端是否引入了桌面端的代码 console.error("Need remove unused code"); @@ -71,6 +72,7 @@ export class Layout { } addWnd(child: Wnd, id?: string) { + recordBeforeResizeTop(); if (!id) { this.children.splice(this.children.length, 0, child); this.element.append(child.element); diff --git a/app/src/protyle/util/resize.ts b/app/src/protyle/util/resize.ts index 1cb09df2c..8a169041c 100644 --- a/app/src/protyle/util/resize.ts +++ b/app/src/protyle/util/resize.ts @@ -4,6 +4,30 @@ import {hasClosestBlock} from "./hasClosest"; import {Constants} from "../../constants"; import {lineNumberRender} from "../render/highlightRender"; import {stickyRow} from "../render/av/row"; +import {getAllModels} from "../../layout/getAll"; + +export const recordBeforeResizeTop = () => { + getAllModels().editor.forEach((item) => { + if (item.editor && item.editor.protyle && + item.element.parentElement && !item.element.classList.contains("fn__none")) { + item.editor.protyle.wysiwyg.element.querySelector('[data-resize-top]')?.removeAttribute("data-resize-top"); + const contentRect = item.editor.protyle.contentElement.getBoundingClientRect() + let topElement = document.elementFromPoint(contentRect.left + (contentRect.width / 2), contentRect.top); + if (!topElement) { + topElement = document.elementFromPoint(contentRect.left + (contentRect.width / 2), contentRect.top + 17); + } + if (!topElement) { + return; + } + topElement = hasClosestBlock(topElement) as HTMLElement; + if (!topElement) { + return; + } + console.log(topElement) + topElement.setAttribute("data-resize-top", topElement.getBoundingClientRect().top.toString()); + } + }); +} export const resize = (protyle: IProtyle) => { hideElements(["gutterOnly"], protyle); @@ -36,23 +60,12 @@ export const resize = (protyle: IProtyle) => { lineNumberRender(item.parentElement); } }); - // 保持光标位置不变 https://ld246.com/article/1673704873983/comment/1673765814595#comments - if (!protyle.disabled && protyle.toolbar.range) { - let rangeRect = protyle.toolbar.range.getBoundingClientRect(); - if (rangeRect.height === 0) { - const blockElement = hasClosestBlock(protyle.toolbar.range.startContainer); - if (blockElement) { - rangeRect = blockElement.getBoundingClientRect(); - } - } - if (rangeRect.height === 0) { - return; - } - const protyleRect = protyle.element.getBoundingClientRect(); - if (protyleRect.top + 30 > rangeRect.top || protyleRect.bottom < rangeRect.bottom) { - protyle.toolbar.range.startContainer.parentElement.scrollIntoView(protyleRect.top > rangeRect.top); - } - } } - }, Constants.TIMEOUT_TRANSITION); // 等待 setPadding 动画结束 + const topElement = protyle.wysiwyg.element.querySelector('[data-resize-top]'); + if (topElement) { + topElement.scrollIntoView(); + protyle.contentElement.scrollTop += topElement.getBoundingClientRect().top - parseInt(topElement.getAttribute("data-resize-top")); + topElement.removeAttribute("data-resize-top"); + } + }, Constants.TIMEOUT_TRANSITION + 100); // 等待 setPadding 动画结束 }; diff --git a/app/src/util/backForward.ts b/app/src/util/backForward.ts index 2f01a4c64..0e762a9e6 100644 --- a/app/src/util/backForward.ts +++ b/app/src/util/backForward.ts @@ -115,7 +115,6 @@ const focusStack = async (app: App, stack: IBackStack) => { if (stack.protyle.title.editElement.getBoundingClientRect().height === 0) { // 切换 tab stack.protyle.model.parent.parent.switchTab(stack.protyle.model.parent.headElement); - // 需要更新 range,否则 resize 中 `保持光标位置不变` 会导致光标跳动 stack.protyle.toolbar.range = undefined; } focusByOffset(stack.protyle.title.editElement, stack.position.start, stack.position.end);