Vanessa 2022-08-07 17:56:07 +08:00
parent bedb811d6e
commit fff0504935
10 changed files with 48 additions and 27 deletions

View file

@ -14,7 +14,8 @@ export class Editor extends Model {
tab: Tab,
blockId: string,
mode?: TEditorMode,
action?: string[]
action?: string[],
scrollAttr?: string
}) {
super({
id: options.tab.id,
@ -31,6 +32,7 @@ export class Editor extends Model {
blockId: string,
action?: string[]
mode?: TEditorMode,
scrollAttr?: string
}) {
this.editor = new Protyle(this.element, {
action: options.action,
@ -41,6 +43,7 @@ export class Editor extends Model {
background: true,
scroll: true,
},
scrollAttr: options.scrollAttr,
typewriterMode: true,
after: (editor) => {
if (window.siyuan.config.readonly) {

View file

@ -25,6 +25,7 @@ import {getContenteditableElement} from "../protyle/wysiwyg/getBlock";
import {updatePanelByEditor} from "../editor/util";
import {Constants} from "../constants";
import {openSearch} from "../search/spread";
import {saveScroll} from "../protyle/scroll/saveScroll";
export const setPanelFocus = (element: Element) => {
if (element.classList.contains("block__icons--active") || element.classList.contains("layout__wnd--active")) {
@ -210,7 +211,8 @@ const JSONToCenter = (json: any, layout?: Layout | Wnd | Tab | Model) => {
tab: (layout as Tab),
blockId: json.blockId,
mode: json.mode,
action: [json.action]
action: [json.action],
scrollAttr: json.scrollAttr,
}));
} else if (json.instance === "Asset") {
(layout as Tab).addModel(new Asset({
@ -364,6 +366,7 @@ export const layoutToJSON = (layout: Layout | Wnd | Tab | Model, json: any) => {
json.mode = layout.editor.protyle.preview.element.classList.contains("fn__none") ? "wysiwyg" : "preview";
json.action = layout.editor.protyle.block.showAll ? Constants.CB_GET_ALL : "";
json.instance = "Editor";
json.scrollAttr = saveScroll(layout.editor.protyle, true);
} else if (layout instanceof Asset) {
json.path = layout.path;
json.instance = "Asset";
@ -470,7 +473,8 @@ export const copyTab = (tab: Tab) => {
if (tab.model instanceof Editor) {
model = new Editor({
tab: newTab,
blockId: tab.model.editor.protyle.block.rootID
blockId: tab.model.editor.protyle.block.rootID,
scrollAttr: saveScroll(tab.model.editor.protyle, true)
});
} else if (tab.model instanceof Asset) {
model = new Asset({

View file

@ -5,12 +5,15 @@ import {addLoading, setPadding} from "../ui/initUI";
import {fetchPost} from "../../util/fetch";
import {Constants} from "../../constants";
import {onGet} from "../util/onGet";
import {saveScroll} from "../scroll/saveScroll";
import {hideElements} from "../ui/hideElements";
export const netImg2LocalAssets = (protyle: IProtyle) => {
if (protyle.element.querySelector(".fn__loading")) {
return;
}
addLoading(protyle);
hideElements(["toolbar"], protyle);
fetchPost("/api/format/netImg2LocalAssets", {
id: protyle.block.rootID
}, () => {
@ -20,7 +23,7 @@ export const netImg2LocalAssets = (protyle: IProtyle) => {
mode: 0,
size: Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
/// #else
getAllModels().editor.forEach(item => {
@ -30,7 +33,7 @@ export const netImg2LocalAssets = (protyle: IProtyle) => {
mode: 0,
size: Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, item.editor.protyle, [Constants.CB_GET_FOCUS]);
onGet(getResponse, item.editor.protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
}
});

View file

@ -22,6 +22,8 @@ import {getAllModels} from "../../layout/getAll";
import {getCurrentWindow} from "@electron/remote";
/// #endif
import {onGet} from "../util/onGet";
import {saveScroll} from "../scroll/saveScroll";
import {hideElements} from "../ui/hideElements";
export class Breadcrumb {
public element: HTMLElement;
@ -218,7 +220,7 @@ export class Breadcrumb {
label: window.siyuan.languages.netImg2LocalAsset,
icon: "iconTransform",
accelerator: window.siyuan.config.keymap.editor.general.netImg2LocalAsset.custom,
click () {
click() {
netImg2LocalAssets(protyle);
}
}).element);
@ -226,6 +228,7 @@ export class Breadcrumb {
label: window.siyuan.languages.optimizeTypography,
icon: "iconFormat",
click: () => {
hideElements(["toolbar"], protyle);
fetchPost("/api/format/autoSpace", {
id: protyle.block.rootID
}, () => {
@ -235,7 +238,7 @@ export class Breadcrumb {
mode: 0,
size: Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]);
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
/// #else
getAllModels().editor.forEach(item => {
@ -245,7 +248,7 @@ export class Breadcrumb {
mode: 0,
size: Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, item.editor.protyle, [Constants.CB_GET_FOCUS]);
onGet(getResponse, item.editor.protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
}
});
@ -274,7 +277,7 @@ export class Breadcrumb {
mode: 0,
size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, protyle, protyle.block.showAll ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS]);
onGet(getResponse, protyle, protyle.block.showAll ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
}
}).element);

View file

@ -325,9 +325,9 @@ ${window.siyuan.languages.createdAt} ${dayjs(response.data.ial.id.substr(0, 14))
}
}
public render(protyle: IProtyle, refresh = false, action:string[] = []) {
public render(protyle: IProtyle, refresh = false, scrollAttr?: string) {
if (this.editElement.getAttribute("data-render") === "true" && !refresh) {
return;
return false;
}
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
@ -360,9 +360,8 @@ ${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);
if (scrollAttr) {
restoreScroll(protyle, scrollAttr === Constants.CB_GET_SCROLL ? undefined : scrollAttr);
}
});
}

View file

@ -160,7 +160,7 @@ class Protyle {
mode: (options.action && options.action.includes(Constants.CB_GET_CONTEXT)) ? 3 : 0, // 0: 仅当前 ID默认值1向上 2向下3上下都加载4加载最后
size: options.action?.includes(Constants.CB_GET_ALL) ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, this.protyle, options.action);
onGet(getResponse, this.protyle, options.action, options.scrollAttr);
if (this.protyle.model) {
/// #if !MOBILE
if (options.action?.includes(Constants.CB_GET_FOCUS)) {

View file

@ -3,11 +3,9 @@ import {hasClosestBlock} from "../util/hasClosest";
import {focusByOffset, getSelectionOffset} from "../util/selection";
import {fetchPost} from "../../util/fetch";
import {zoomOut} from "../../menus/protyle";
import {preventScroll} from "./preventScroll";
export const saveScroll = (protyle: IProtyle) => {
if (protyle.contentElement.clientHeight === protyle.contentElement.scrollHeight) {
return;
}
export const saveScroll = (protyle: IProtyle, getString = false) => {
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) {
@ -24,17 +22,20 @@ export const saveScroll = (protyle: IProtyle) => {
if (protyle.block.showAll) {
attr += `${Constants.ZWSP}${protyle.block.id}`;
}
if (getString) {
return attr;
}
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")
export const restoreScroll = (protyle: IProtyle, scrollAttr?: string) => {
const attr = scrollAttr || protyle.wysiwyg.element.getAttribute("scroll")
if (!attr) {
return
return;
}
preventScroll(protyle);
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) {

View file

@ -14,8 +14,9 @@ import {pushBack} from "../../util/backForward";
import {focusBlock} from "./selection";
import {hasClosestByAttribute, hasClosestByClassName} from "./hasClosest";
import {preventScroll} from "../scroll/preventScroll";
import {restoreScroll} from "../scroll/saveScroll";
export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[] = []) => {
export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[] = [], scrollAttr?: string) => {
const loadingElement = protyle.element.querySelector(".fn__loading");
if (loadingElement) {
loadingElement.remove();
@ -80,7 +81,8 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
}
if (protyle.options.render.title) {
protyle.title.render(protyle, false, action);
// 页签没有打开
protyle.title.render(protyle, false, scrollAttr ? scrollAttr : (action.includes(Constants.CB_GET_SCROLL) ? Constants.CB_GET_SCROLL : null));
} else if (protyle.options.render.background) {
fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID
@ -94,6 +96,10 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
content: html,
action,
}, protyle);
if (scrollAttr && ((protyle.options.render.title && protyle.title.editElement.getAttribute("data-render") === "true") || !protyle.options.render.title)) {
restoreScroll(protyle, scrollAttr);
}
};
const setHTML = (options: { content: string, action?: string[] }, protyle: IProtyle) => {

View file

@ -7,6 +7,7 @@ import {addLoading, setPadding} from "../ui/initUI";
import {Constants} from "../../constants";
import {onGet} from "../util/onGet";
import {openBacklink, openGraph, openOutline} from "../../layout/dock/util";
import {saveScroll} from "../scroll/saveScroll";
export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
const target = event.target as HTMLElement;
@ -21,14 +22,14 @@ export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
return true;
}
if (matchHotKey(window.siyuan.config.keymap.editor.general.refresh.custom, event)) {
protyle.title.render(protyle, true);
protyle.title?.render(protyle, true);
addLoading(protyle);
fetchPost("/api/filetree/getDoc", {
id: protyle.block.showAll ? protyle.block.id : protyle.block.rootID,
mode: 0,
size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => {
onGet(getResponse, protyle, protyle.block.showAll ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS]);
onGet(getResponse, protyle, protyle.block.showAll ? [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
});
event.preventDefault();
event.stopPropagation();

View file

@ -346,6 +346,7 @@ interface IOptions {
mode?: TEditorMode,
blockId: string
key?: string
scrollAttr?: string
defId?: string
render?: {
background?: boolean