A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
1import {hasClosestBlock} from "../util/hasClosest";
2import {getSelectionOffset} from "../util/selection";
3import {fetchPost} from "../../util/fetch";
4import {onGet} from "../util/onGet";
5import {Constants} from "../../constants";
6import {setStorageVal} from "../util/compatibility";
7import {isSupportCSSHL} from "../render/searchMarkRender";
8
9export const saveScroll = (protyle: IProtyle, getObject = false) => {
10 if (!protyle.wysiwyg.element.firstElementChild || window.siyuan.config.readonly) {
11 // 报错或者空白页面
12 return undefined;
13 }
14 const attr: IScrollAttr = {
15 rootId: protyle.block.rootID,
16 startId: protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-id"),
17 endId: protyle.wysiwyg.element.lastElementChild.getAttribute("data-node-id"),
18 scrollTop: protyle.contentElement.scrollTop || parseInt(protyle.contentElement.getAttribute("data-scrolltop")) || 0,
19 };
20 let range: Range;
21 if (getSelection().rangeCount > 0) {
22 range = getSelection().getRangeAt(0);
23 }
24 if (!range || !protyle.wysiwyg.element.contains(range.startContainer)) {
25 range = protyle.toolbar.range;
26 }
27 if (range && protyle.wysiwyg.element.contains(range.startContainer)) {
28 const blockElement = hasClosestBlock(range.startContainer);
29 if (blockElement) {
30 const position = getSelectionOffset(blockElement, undefined, range);
31 attr.focusId = blockElement.getAttribute("data-node-id");
32 attr.focusStart = position.start;
33 attr.focusEnd = position.end;
34 }
35 }
36
37 if (protyle.block.showAll) {
38 attr.zoomInId = protyle.block.id;
39 }
40 if (getObject) {
41 return attr;
42 }
43
44 window.siyuan.storage[Constants.LOCAL_FILEPOSITION][protyle.block.rootID] = attr;
45 return new Promise(resolve => {
46 setStorageVal(Constants.LOCAL_FILEPOSITION, window.siyuan.storage[Constants.LOCAL_FILEPOSITION], () => {
47 resolve(true);
48 });
49 });
50};
51
52export const getDocByScroll = (options: {
53 protyle: IProtyle,
54 scrollAttr?: IScrollAttr,
55 mergedOptions?: IProtyleOptions,
56 cb?: (keys: string[]) => void
57 focus?: boolean,
58 updateReadonly?: boolean
59}) => {
60 let actions: TProtyleAction[] = [];
61 if (options.mergedOptions) {
62 actions = options.mergedOptions.action;
63 } else {
64 if (options.focus) {
65 actions = [Constants.CB_GET_UNUNDO, Constants.CB_GET_FOCUS];
66 } else {
67 actions = [Constants.CB_GET_UNUNDO];
68 }
69 }
70 if (options.scrollAttr?.zoomInId && options.scrollAttr?.rootId && options.scrollAttr.zoomInId !== options.scrollAttr.rootId) {
71 fetchPost("/api/filetree/getDoc", {
72 id: options.scrollAttr.zoomInId,
73 size: Constants.SIZE_GET_MAX,
74 query: options.protyle.query?.key,
75 queryMethod: options.protyle.query?.method,
76 queryTypes: options.protyle.query?.types,
77 highlight: !isSupportCSSHL(),
78 }, response => {
79 if (response.code === 1) {
80 fetchPost("/api/filetree/getDoc", {
81 id: options.scrollAttr.rootId || options.mergedOptions?.blockId || options.protyle.block?.rootID || options.scrollAttr.startId,
82 query: options.protyle.query?.key,
83 queryMethod: options.protyle.query?.method,
84 queryTypes: options.protyle.query?.types,
85 highlight: !isSupportCSSHL(),
86 }, response => {
87 onGet({
88 data: response,
89 protyle: options.protyle,
90 action: actions,
91 scrollAttr: options.scrollAttr,
92 afterCB: options.cb ? () => {
93 options.cb(response.data.keywords);
94 } : undefined,
95 updateReadonly: options.updateReadonly
96 });
97 });
98 } else {
99 actions.push(Constants.CB_GET_ALL);
100 onGet({
101 data: response,
102 protyle: options.protyle,
103 action: actions,
104 scrollAttr: options.scrollAttr,
105 afterCB: options.cb ? () => {
106 options.cb(response.data.keywords);
107 } : undefined,
108 updateReadonly: options.updateReadonly
109 });
110 }
111 });
112 return;
113 }
114 fetchPost("/api/filetree/getDoc", {
115 id: options.scrollAttr?.rootId || options.mergedOptions?.blockId || options.protyle.block?.rootID || options.scrollAttr?.startId,
116 startID: options.scrollAttr?.startId,
117 endID: options.scrollAttr?.endId,
118 query: options.protyle.query?.key,
119 queryMethod: options.protyle.query?.method,
120 queryTypes: options.protyle.query?.types,
121 highlight: !isSupportCSSHL(),
122 }, response => {
123 onGet({
124 data: response,
125 protyle: options.protyle,
126 action: actions,
127 scrollAttr: options.scrollAttr,
128 afterCB: options.cb ? () => {
129 options.cb(response.data.keywords);
130 } : undefined,
131 updateReadonly: options.updateReadonly
132 });
133 });
134};