mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-21 09:00:12 +01:00
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_SETID = "cb-get-setid"; // 重置 blockid
|
||||||
public static readonly CB_GET_ALL = "cb-get-all"; // 获取所有块
|
public static readonly CB_GET_ALL = "cb-get-all"; // 获取所有块
|
||||||
public static readonly CB_GET_UNUNDO = "cb-get-unundo"; // 不需要记录历史
|
public static readonly CB_GET_UNUNDO = "cb-get-unundo"; // 不需要记录历史
|
||||||
|
public static readonly CB_GET_SCROLL = "cb-get-scroll"; // 滚动到指定位置
|
||||||
|
|
||||||
// localstorage
|
// localstorage
|
||||||
public static readonly LOCAL_SEARCHEDATA = "local-searchedata";
|
public static readonly LOCAL_SEARCHEDATA = "local-searchedata";
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import {getAllModels} from "./getAll";
|
||||||
import {fetchPost} from "../util/fetch";
|
import {fetchPost} from "../util/fetch";
|
||||||
import {onGet} from "../protyle/util/onGet";
|
import {onGet} from "../protyle/util/onGet";
|
||||||
import {countBlockWord} from "./status";
|
import {countBlockWord} from "./status";
|
||||||
|
import {saveScroll} from "../protyle/scroll/saveScroll";
|
||||||
|
|
||||||
export class Wnd {
|
export class Wnd {
|
||||||
public id: string;
|
public id: string;
|
||||||
|
|
@ -488,6 +489,9 @@ export class Wnd {
|
||||||
private removeTabAction = (id: string, closeAll = false) => {
|
private removeTabAction = (id: string, closeAll = false) => {
|
||||||
this.children.find((item, index) => {
|
this.children.find((item, index) => {
|
||||||
if (item.id === id) {
|
if (item.id === id) {
|
||||||
|
if (item.model instanceof Editor) {
|
||||||
|
saveScroll(item.model.editor.protyle);
|
||||||
|
}
|
||||||
if (this.children.length === 1) {
|
if (this.children.length === 1) {
|
||||||
this.destroyModel(this.children[0].model);
|
this.destroyModel(this.children[0].model);
|
||||||
this.children = [];
|
this.children = [];
|
||||||
|
|
|
||||||
|
|
@ -235,12 +235,12 @@ export class Files extends Model {
|
||||||
openFileById({
|
openFileById({
|
||||||
id: target.getAttribute("data-node-id"),
|
id: target.getAttribute("data-node-id"),
|
||||||
position: "right",
|
position: "right",
|
||||||
action: [Constants.CB_GET_FOCUS]
|
action: [Constants.CB_GET_FOCUS, Constants.CB_GET_SCROLL]
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
openFileById({
|
openFileById({
|
||||||
id: target.getAttribute("data-node-id"),
|
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") {
|
} 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");
|
const breadcrumbHLElement = protyle.breadcrumb.element.querySelector(".protyle-breadcrumb__item--active");
|
||||||
if (breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === id) {
|
if (breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === id) {
|
||||||
if (id === protyle.block.rootID) {
|
if (id === protyle.block.rootID) {
|
||||||
|
|
@ -393,6 +393,9 @@ export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushB
|
||||||
updateBacklinkGraph(getAllModels(), protyle);
|
updateBacklinkGraph(getAllModels(), protyle);
|
||||||
}
|
}
|
||||||
/// #endif
|
/// #endif
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ import {getNoContainerElement} from "../wysiwyg/getBlock";
|
||||||
import {commonHotkey} from "../wysiwyg/commonHotkey";
|
import {commonHotkey} from "../wysiwyg/commonHotkey";
|
||||||
import {code160to32} from "../util/code160to32";
|
import {code160to32} from "../util/code160to32";
|
||||||
import {deleteFile} from "../../editor/deleteFile";
|
import {deleteFile} from "../../editor/deleteFile";
|
||||||
|
import {restoreScroll} from "../scroll/saveScroll";
|
||||||
|
|
||||||
export class Title {
|
export class Title {
|
||||||
public element: HTMLElement;
|
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) {
|
if (this.editElement.getAttribute("data-render") === "true" && !refresh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -359,6 +360,10 @@ ${window.siyuan.languages.createdAt} ${dayjs(response.data.ial.id.substr(0, 14))
|
||||||
range.selectNodeContents(this.editElement);
|
range.selectNodeContents(this.editElement);
|
||||||
focusByRange(range);
|
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) {
|
if (protyle.options.render.title) {
|
||||||
protyle.title.render(protyle);
|
protyle.title.render(protyle, false, action);
|
||||||
} else if (protyle.options.render.background) {
|
} else if (protyle.options.render.background) {
|
||||||
fetchPost("/api/block/getDocInfo", {
|
fetchPost("/api/block/getDocInfo", {
|
||||||
id: protyle.block.rootID
|
id: protyle.block.rootID
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ export class WYSIWYG {
|
||||||
const ialKeys = Object.keys(ial);
|
const ialKeys = Object.keys(ial);
|
||||||
for (let i = 0; i < this.element.attributes.length; i++) {
|
for (let i = 0; i < this.element.attributes.length; i++) {
|
||||||
const oldKey = this.element.attributes[i].nodeName;
|
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)) {
|
!ialKeys.includes(oldKey)) {
|
||||||
this.element.removeAttribute(oldKey);
|
this.element.removeAttribute(oldKey);
|
||||||
i--;
|
i--;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue