This commit is contained in:
parent
d93023fc8a
commit
72fba69115
8 changed files with 78 additions and 6 deletions
|
@ -50,6 +50,7 @@ export abstract class Constants {
|
|||
public static readonly CB_GET_SETID = "cb-get-setid"; // 重置 blockid
|
||||
public static readonly CB_GET_ALL = "cb-get-all"; // 获取所有块
|
||||
public static readonly CB_GET_UNUNDO = "cb-get-unundo"; // 不需要记录历史
|
||||
public static readonly CB_GET_SCROLL = "cb-get-scroll"; // 滚动到指定位置
|
||||
|
||||
// localstorage
|
||||
public static readonly LOCAL_SEARCHEDATA = "local-searchedata";
|
||||
|
|
|
@ -26,6 +26,7 @@ import {getAllModels} from "./getAll";
|
|||
import {fetchPost} from "../util/fetch";
|
||||
import {onGet} from "../protyle/util/onGet";
|
||||
import {countBlockWord} from "./status";
|
||||
import {saveScroll} from "../protyle/scroll/saveScroll";
|
||||
|
||||
export class Wnd {
|
||||
public id: string;
|
||||
|
@ -488,6 +489,9 @@ export class Wnd {
|
|||
private removeTabAction = (id: string, closeAll = false) => {
|
||||
this.children.find((item, index) => {
|
||||
if (item.id === id) {
|
||||
if (item.model instanceof Editor) {
|
||||
saveScroll(item.model.editor.protyle);
|
||||
}
|
||||
if (this.children.length === 1) {
|
||||
this.destroyModel(this.children[0].model);
|
||||
this.children = [];
|
||||
|
|
|
@ -235,12 +235,12 @@ export class Files extends Model {
|
|||
openFileById({
|
||||
id: target.getAttribute("data-node-id"),
|
||||
position: "right",
|
||||
action: [Constants.CB_GET_FOCUS]
|
||||
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
|
||||
});
|
||||
} else {
|
||||
openFileById({
|
||||
id: target.getAttribute("data-node-id"),
|
||||
action: [Constants.CB_GET_FOCUS]
|
||||
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
|
||||
});
|
||||
}
|
||||
} else if (target.getAttribute("data-type") === "navigation-root") {
|
||||
|
|
|
@ -338,7 +338,7 @@ export const contentMenu = (protyle: IProtyle, nodeElement: Element) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushBack = true) => {
|
||||
export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushBack = true, callback?: () => void) => {
|
||||
const breadcrumbHLElement = protyle.breadcrumb.element.querySelector(".protyle-breadcrumb__item--active");
|
||||
if (breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === id) {
|
||||
if (id === protyle.block.rootID) {
|
||||
|
@ -393,6 +393,9 @@ export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushB
|
|||
updateBacklinkGraph(getAllModels(), protyle);
|
||||
}
|
||||
/// #endif
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import {getNoContainerElement} from "../wysiwyg/getBlock";
|
|||
import {commonHotkey} from "../wysiwyg/commonHotkey";
|
||||
import {code160to32} from "../util/code160to32";
|
||||
import {deleteFile} from "../../editor/deleteFile";
|
||||
import {restoreScroll} from "../scroll/saveScroll";
|
||||
|
||||
export class Title {
|
||||
public element: HTMLElement;
|
||||
|
@ -324,7 +325,7 @@ ${window.siyuan.languages.createdAt} ${dayjs(response.data.ial.id.substr(0, 14))
|
|||
}
|
||||
}
|
||||
|
||||
public render(protyle: IProtyle, refresh = false) {
|
||||
public render(protyle: IProtyle, refresh = false, action:string[] = []) {
|
||||
if (this.editElement.getAttribute("data-render") === "true" && !refresh) {
|
||||
return;
|
||||
}
|
||||
|
@ -359,6 +360,10 @@ ${window.siyuan.languages.createdAt} ${dayjs(response.data.ial.id.substr(0, 14))
|
|||
range.selectNodeContents(this.editElement);
|
||||
focusByRange(range);
|
||||
}
|
||||
|
||||
if (action.includes(Constants.CB_GET_SCROLL)) {
|
||||
restoreScroll(protyle);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
59
app/src/protyle/scroll/saveScroll.ts
Normal file
59
app/src/protyle/scroll/saveScroll.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
import {Constants} from "../../constants";
|
||||
import {hasClosestBlock} from "../util/hasClosest";
|
||||
import {focusByOffset, getSelectionOffset} from "../util/selection";
|
||||
import {fetchPost} from "../../util/fetch";
|
||||
import {zoomOut} from "../../menus/protyle";
|
||||
|
||||
export const saveScroll = (protyle: IProtyle) => {
|
||||
if (protyle.contentElement.clientHeight === protyle.contentElement.scrollHeight) {
|
||||
return;
|
||||
}
|
||||
let attr = `${protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id")}${Constants.ZWSP}${protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id")}${Constants.ZWSP}${protyle.contentElement.scrollTop}`;
|
||||
let range: Range
|
||||
if (getSelection().rangeCount > 0) {
|
||||
range = getSelection().getRangeAt(0)
|
||||
}
|
||||
|
||||
if (range && protyle.wysiwyg.element.contains(range.startContainer)) {
|
||||
const blockElement = hasClosestBlock(range.startContainer);
|
||||
if (blockElement) {
|
||||
const position = getSelectionOffset(blockElement, undefined, range);
|
||||
attr += `${Constants.ZWSP}${blockElement.getAttribute("data-node-id")}${Constants.ZWSP}${position.start}${Constants.ZWSP}${position.end}`;
|
||||
}
|
||||
}
|
||||
if (protyle.block.showAll) {
|
||||
attr += `${Constants.ZWSP}${protyle.block.id}`;
|
||||
}
|
||||
|
||||
fetchPost("/api/attr/setBlockAttrs", {id: protyle.block.rootID, attrs: {scroll: attr}}, () => {
|
||||
protyle.wysiwyg.element.setAttribute("scroll", attr);
|
||||
});
|
||||
}
|
||||
|
||||
export const restoreScroll = (protyle: IProtyle) => {
|
||||
const attr = protyle.wysiwyg.element.getAttribute("scroll")
|
||||
if (!attr) {
|
||||
return
|
||||
}
|
||||
const [startId, endId, scrollTop, focusId, focusStart, focusEnd, zoomInId] = attr.split(Constants.ZWSP);
|
||||
if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") === startId &&
|
||||
protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id") === endId) {
|
||||
protyle.contentElement.scrollTop = parseInt(scrollTop);
|
||||
focusByOffset(protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId}"]`), parseInt(focusStart), parseInt(focusEnd));
|
||||
} else if (zoomInId && protyle.block.id !== zoomInId) {
|
||||
zoomOut(protyle, zoomInId, undefined, false, () => {
|
||||
protyle.contentElement.scrollTop = parseInt(scrollTop);
|
||||
focusByOffset(protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId}"]`), parseInt(focusStart), parseInt(focusEnd));
|
||||
});
|
||||
} else if (!protyle.scroll.element.classList.contains("fn__none")) {
|
||||
fetchPost("/api/filetree/getDoc", {
|
||||
id: protyle.block.id,
|
||||
startID: startId,
|
||||
endID: endId,
|
||||
}, getResponse => {
|
||||
protyle.wysiwyg.element.innerHTML = getResponse.data.content;
|
||||
protyle.contentElement.scrollTop = parseInt(scrollTop);
|
||||
focusByOffset(protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId}"]`), parseInt(focusStart), parseInt(focusEnd));
|
||||
})
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
|
|||
}
|
||||
|
||||
if (protyle.options.render.title) {
|
||||
protyle.title.render(protyle);
|
||||
protyle.title.render(protyle, false, action);
|
||||
} else if (protyle.options.render.background) {
|
||||
fetchPost("/api/block/getDocInfo", {
|
||||
id: protyle.block.rootID
|
||||
|
|
|
@ -86,7 +86,7 @@ export class WYSIWYG {
|
|||
const ialKeys = Object.keys(ial);
|
||||
for (let i = 0; i < this.element.attributes.length; i++) {
|
||||
const oldKey = this.element.attributes[i].nodeName;
|
||||
if (!["type", "class", "spellcheck", "contenteditable", "data-doc-type", "style"].includes(oldKey) &&
|
||||
if (!["type", "class", "spellcheck", "contenteditable", "data-doc-type", "style", "scroll"].includes(oldKey) &&
|
||||
!ialKeys.includes(oldKey)) {
|
||||
this.element.removeAttribute(oldKey);
|
||||
i--;
|
||||
|
|
Loading…
Add table
Reference in a new issue