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

View file

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

View file

@ -5,12 +5,15 @@ import {addLoading, setPadding} from "../ui/initUI";
import {fetchPost} from "../../util/fetch"; import {fetchPost} from "../../util/fetch";
import {Constants} from "../../constants"; import {Constants} from "../../constants";
import {onGet} from "../util/onGet"; import {onGet} from "../util/onGet";
import {saveScroll} from "../scroll/saveScroll";
import {hideElements} from "../ui/hideElements";
export const netImg2LocalAssets = (protyle: IProtyle) => { export const netImg2LocalAssets = (protyle: IProtyle) => {
if (protyle.element.querySelector(".fn__loading")) { if (protyle.element.querySelector(".fn__loading")) {
return; return;
} }
addLoading(protyle); addLoading(protyle);
hideElements(["toolbar"], protyle);
fetchPost("/api/format/netImg2LocalAssets", { fetchPost("/api/format/netImg2LocalAssets", {
id: protyle.block.rootID id: protyle.block.rootID
}, () => { }, () => {
@ -20,7 +23,7 @@ export const netImg2LocalAssets = (protyle: IProtyle) => {
mode: 0, mode: 0,
size: Constants.SIZE_GET, size: Constants.SIZE_GET,
}, getResponse => { }, getResponse => {
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]); onGet(getResponse, protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
}); });
/// #else /// #else
getAllModels().editor.forEach(item => { getAllModels().editor.forEach(item => {
@ -30,7 +33,7 @@ export const netImg2LocalAssets = (protyle: IProtyle) => {
mode: 0, mode: 0,
size: Constants.SIZE_GET, size: Constants.SIZE_GET,
}, getResponse => { }, 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"; import {getCurrentWindow} from "@electron/remote";
/// #endif /// #endif
import {onGet} from "../util/onGet"; import {onGet} from "../util/onGet";
import {saveScroll} from "../scroll/saveScroll";
import {hideElements} from "../ui/hideElements";
export class Breadcrumb { export class Breadcrumb {
public element: HTMLElement; public element: HTMLElement;
@ -218,7 +220,7 @@ export class Breadcrumb {
label: window.siyuan.languages.netImg2LocalAsset, label: window.siyuan.languages.netImg2LocalAsset,
icon: "iconTransform", icon: "iconTransform",
accelerator: window.siyuan.config.keymap.editor.general.netImg2LocalAsset.custom, accelerator: window.siyuan.config.keymap.editor.general.netImg2LocalAsset.custom,
click () { click() {
netImg2LocalAssets(protyle); netImg2LocalAssets(protyle);
} }
}).element); }).element);
@ -226,6 +228,7 @@ export class Breadcrumb {
label: window.siyuan.languages.optimizeTypography, label: window.siyuan.languages.optimizeTypography,
icon: "iconFormat", icon: "iconFormat",
click: () => { click: () => {
hideElements(["toolbar"], protyle);
fetchPost("/api/format/autoSpace", { fetchPost("/api/format/autoSpace", {
id: protyle.block.rootID id: protyle.block.rootID
}, () => { }, () => {
@ -235,7 +238,7 @@ export class Breadcrumb {
mode: 0, mode: 0,
size: Constants.SIZE_GET, size: Constants.SIZE_GET,
}, getResponse => { }, getResponse => {
onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]); onGet(getResponse, protyle, [Constants.CB_GET_FOCUS], saveScroll(protyle, true));
}); });
/// #else /// #else
getAllModels().editor.forEach(item => { getAllModels().editor.forEach(item => {
@ -245,7 +248,7 @@ export class Breadcrumb {
mode: 0, mode: 0,
size: Constants.SIZE_GET, size: Constants.SIZE_GET,
}, getResponse => { }, 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, mode: 0,
size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET, size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => { }, 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); }).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) { if (this.editElement.getAttribute("data-render") === "true" && !refresh) {
return; return false;
} }
fetchPost("/api/block/getDocInfo", { fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID id: protyle.block.rootID
@ -360,9 +360,8 @@ ${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 (scrollAttr) {
if (action.includes(Constants.CB_GET_SCROLL)) { restoreScroll(protyle, scrollAttr === Constants.CB_GET_SCROLL ? undefined : scrollAttr);
restoreScroll(protyle);
} }
}); });
} }

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加载最后 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, size: options.action?.includes(Constants.CB_GET_ALL) ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => { }, getResponse => {
onGet(getResponse, this.protyle, options.action); onGet(getResponse, this.protyle, options.action, options.scrollAttr);
if (this.protyle.model) { if (this.protyle.model) {
/// #if !MOBILE /// #if !MOBILE
if (options.action?.includes(Constants.CB_GET_FOCUS)) { 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 {focusByOffset, getSelectionOffset} from "../util/selection";
import {fetchPost} from "../../util/fetch"; import {fetchPost} from "../../util/fetch";
import {zoomOut} from "../../menus/protyle"; import {zoomOut} from "../../menus/protyle";
import {preventScroll} from "./preventScroll";
export const saveScroll = (protyle: IProtyle) => { export const saveScroll = (protyle: IProtyle, getString = false) => {
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 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 let range: Range
if (getSelection().rangeCount > 0) { if (getSelection().rangeCount > 0) {
@ -24,17 +22,20 @@ export const saveScroll = (protyle: IProtyle) => {
if (protyle.block.showAll) { if (protyle.block.showAll) {
attr += `${Constants.ZWSP}${protyle.block.id}`; attr += `${Constants.ZWSP}${protyle.block.id}`;
} }
if (getString) {
return attr;
}
fetchPost("/api/attr/setBlockAttrs", {id: protyle.block.rootID, attrs: {scroll: attr}}, () => { fetchPost("/api/attr/setBlockAttrs", {id: protyle.block.rootID, attrs: {scroll: attr}}, () => {
protyle.wysiwyg.element.setAttribute("scroll", attr); protyle.wysiwyg.element.setAttribute("scroll", attr);
}); });
} }
export const restoreScroll = (protyle: IProtyle) => { export const restoreScroll = (protyle: IProtyle, scrollAttr?: string) => {
const attr = protyle.wysiwyg.element.getAttribute("scroll") const attr = scrollAttr || protyle.wysiwyg.element.getAttribute("scroll")
if (!attr) { if (!attr) {
return return;
} }
preventScroll(protyle);
const [startId, endId, scrollTop, focusId, focusStart, focusEnd, zoomInId] = attr.split(Constants.ZWSP); const [startId, endId, scrollTop, focusId, focusStart, focusEnd, zoomInId] = attr.split(Constants.ZWSP);
if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") === startId && if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id") === startId &&
protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id") === endId) { 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 {focusBlock} from "./selection";
import {hasClosestByAttribute, hasClosestByClassName} from "./hasClosest"; import {hasClosestByAttribute, hasClosestByClassName} from "./hasClosest";
import {preventScroll} from "../scroll/preventScroll"; 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"); const loadingElement = protyle.element.querySelector(".fn__loading");
if (loadingElement) { if (loadingElement) {
loadingElement.remove(); loadingElement.remove();
@ -80,7 +81,8 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
} }
if (protyle.options.render.title) { 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) { } else if (protyle.options.render.background) {
fetchPost("/api/block/getDocInfo", { fetchPost("/api/block/getDocInfo", {
id: protyle.block.rootID id: protyle.block.rootID
@ -94,6 +96,10 @@ export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[]
content: html, content: html,
action, action,
}, protyle); }, 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) => { 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 {Constants} from "../../constants";
import {onGet} from "../util/onGet"; import {onGet} from "../util/onGet";
import {openBacklink, openGraph, openOutline} from "../../layout/dock/util"; import {openBacklink, openGraph, openOutline} from "../../layout/dock/util";
import {saveScroll} from "../scroll/saveScroll";
export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => { export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
const target = event.target as HTMLElement; const target = event.target as HTMLElement;
@ -21,14 +22,14 @@ export const commonHotkey = (protyle: IProtyle, event: KeyboardEvent) => {
return true; return true;
} }
if (matchHotKey(window.siyuan.config.keymap.editor.general.refresh.custom, event)) { if (matchHotKey(window.siyuan.config.keymap.editor.general.refresh.custom, event)) {
protyle.title.render(protyle, true); protyle.title?.render(protyle, true);
addLoading(protyle); addLoading(protyle);
fetchPost("/api/filetree/getDoc", { fetchPost("/api/filetree/getDoc", {
id: protyle.block.showAll ? protyle.block.id : protyle.block.rootID, id: protyle.block.showAll ? protyle.block.id : protyle.block.rootID,
mode: 0, mode: 0,
size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET, size: protyle.block.showAll ? Constants.SIZE_GET_MAX : Constants.SIZE_GET,
}, getResponse => { }, 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.preventDefault();
event.stopPropagation(); event.stopPropagation();

View file

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