diff --git a/app/src/boot/globalShortcut.ts b/app/src/boot/globalShortcut.ts index 176399ed3..b82bc7fc9 100644 --- a/app/src/boot/globalShortcut.ts +++ b/app/src/boot/globalShortcut.ts @@ -810,7 +810,7 @@ export const globalShortcut = (app: App) => { app.plugins.find(item => { item.commands.find(command => { if (command.callback && - !command.fileTreeCallback && !command.editorCallback&& !command.dockCallback + !command.fileTreeCallback && !command.editorCallback && !command.dockCallback && matchHotKey(command.customHotkey, event)) { matchCommand = true; command.callback(); @@ -1071,7 +1071,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => { selectElements = [nodeElement]; } movePathTo((toPath) => { - hintMoveBlock(toPath[0], selectElements, protyle); + hintMoveBlock(toPath[0], selectElements, protyle, app); }); } event.preventDefault(); @@ -1084,7 +1084,7 @@ const editKeydown = (app: App, event: KeyboardEvent) => { return false; } if (matchHotKey(window.siyuan.config.keymap.editor.general.refresh.custom, event)) { - reloadProtyle(protyle, true); + reloadProtyle(protyle, app, true); event.preventDefault(); return true; } @@ -1106,19 +1106,19 @@ const editKeydown = (app: App, event: KeyboardEvent) => { id: protyle.block.parentID, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle); + onGet({data: getResponse, protyle, app}); }); event.preventDefault(); return true; } // 没有光标时,无法撤销 https://ld246.com/article/1624021111567 if (matchHotKey(window.siyuan.config.keymap.editor.general.undo.custom, event)) { - protyle.undo.undo(protyle); + protyle.undo.undo(app, protyle); event.preventDefault(); return true; } if (matchHotKey(window.siyuan.config.keymap.editor.general.redo.custom, event)) { - protyle.undo.redo(protyle); + protyle.undo.redo(app, protyle); event.preventDefault(); return true; } diff --git a/app/src/card/openCard.ts b/app/src/card/openCard.ts index ad63367a0..a012c3b0f 100644 --- a/app/src/card/openCard.ts +++ b/app/src/card/openCard.ts @@ -143,7 +143,12 @@ export const bindCardEvent = (options: { mode: 0, size: Constants.SIZE_GET_MAX }, (response) => { - onGet(response, editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]); + onGet({ + data: response, + protyle: editor.protyle, + action: [Constants.CB_GET_ALL, Constants.CB_GET_HTML], + app: options.app + }); }); } (options.element.firstElementChild as HTMLElement).style.zIndex = "200"; @@ -163,6 +168,7 @@ export const bindCardEvent = (options: { options.blocks = treeCards.data.cards; if (options.blocks.length > 0) { nextCard({ + app: options.app, countElement, editor, actionElements, @@ -336,6 +342,7 @@ export const bindCardEvent = (options: { if (index > 0) { index--; nextCard({ + app: options.app, countElement, editor, actionElements, @@ -379,6 +386,7 @@ export const bindCardEvent = (options: { } } else { nextCard({ + app: options.app, countElement, editor, actionElements, @@ -390,6 +398,7 @@ export const bindCardEvent = (options: { return; } nextCard({ + app: options.app, countElement, editor, actionElements, @@ -449,6 +458,7 @@ export const openCardByData = (app: App, cardsData: { }; const nextCard = (options: { + app: App, countElement: Element, editor: Protyle, actionElements: NodeListOf, index: number, blocks: ICard[] }) => { options.editor.protyle.element.classList.add("card__block--hide"); @@ -477,7 +487,12 @@ const nextCard = (options: { mode: 0, size: Constants.SIZE_GET_MAX }, (response) => { - onGet(response, options.editor.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]); + onGet({ + data: response, + protyle: options.editor.protyle, + action: [Constants.CB_GET_ALL, Constants.CB_GET_HTML], + app: options.app + }); }); }; diff --git a/app/src/card/viewCards.ts b/app/src/card/viewCards.ts index 23756e4d0..60371a94a 100644 --- a/app/src/card/viewCards.ts +++ b/app/src/card/viewCards.ts @@ -68,7 +68,7 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr if (window.siyuan.config.editor.readOnly) { disabledProtyle(edit.protyle); } - getArticle(edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); + getArticle(app, edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); } const previousElement = dialog.element.querySelector('[data-type="previous"]'); const nextElement = dialog.element.querySelector('[data-type="next"]'); @@ -93,7 +93,7 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr if (currentRect.top < parentRect.top || currentRect.bottom > parentRect.bottom) { currentElement.scrollIntoView(currentRect.top < parentRect.top); } - getArticle(edit, currentElement.getAttribute("data-id")); + getArticle(app, edit, currentElement.getAttribute("data-id")); currentElement.classList.add("b3-list-item--focus"); } event.stopPropagation(); @@ -125,7 +125,7 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr nextElement.nextElementSibling.nextElementSibling.textContent = `${pageIndex}/${cardsResponse.data.pageCount || 1}`; listElement.innerHTML = renderViewItem(cardsResponse.data.blocks, title, deckType); listElement.scrollTop = 0; - getArticle(edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); + getArticle(app, edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); }); event.stopPropagation(); event.preventDefault(); @@ -145,13 +145,13 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr nextElement.nextElementSibling.nextElementSibling.textContent = `${pageIndex}/${cardsResponse.data.pageCount || 1}`; listElement.innerHTML = renderViewItem(cardsResponse.data.blocks, title, deckType); listElement.scrollTop = 0; - getArticle(edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); + getArticle(app, edit, dialog.element.querySelector(".b3-list-item--focus")?.getAttribute("data-id")); }); event.stopPropagation(); event.preventDefault(); break; } else if (type === "card-item") { - getArticle(edit, target.getAttribute("data-id")); + getArticle(app, edit, target.getAttribute("data-id")); listElement.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); target.classList.add("b3-list-item--focus"); event.stopPropagation(); @@ -171,10 +171,10 @@ export const viewCards = (app: App, deckID: string, title: string, deckType: "Tr } if (!nextElment) { - getArticle(edit, ""); + getArticle(app, edit, ""); listElement.innerHTML = `
${window.siyuan.languages.emptyContent}
`; } else { - getArticle(edit, nextElment.getAttribute("data-id")); + getArticle(app, edit, nextElment.getAttribute("data-id")); listElement.querySelector(".b3-list-item--focus")?.classList.remove("b3-list-item--focus"); nextElment.classList.add("b3-list-item--focus"); target.parentElement.remove(); @@ -240,7 +240,7 @@ ${unicode2Emoji(item.ial.icon, false, "b3-list-item__graphic", true)} }; -const getArticle = (edit: Protyle, id: string) => { +const getArticle = (app: App, edit: Protyle, id: string) => { if (!id) { edit.protyle.element.classList.add("fn__none"); edit.protyle.element.nextElementSibling.classList.remove("fn__none"); @@ -255,6 +255,8 @@ const getArticle = (edit: Protyle, id: string) => { mode: 0, size: Constants.SIZE_GET_MAX, }, getResponse => { - onGet(getResponse, edit.protyle, [Constants.CB_GET_ALL, Constants.CB_GET_HTML]); + onGet({ + data: getResponse, protyle: edit.protyle, action: [Constants.CB_GET_ALL, Constants.CB_GET_HTML], app + }); }); }; diff --git a/app/src/config/editor.ts b/app/src/config/editor.ts index b39426a6c..cab6a27a2 100644 --- a/app/src/config/editor.ts +++ b/app/src/config/editor.ts @@ -5,6 +5,7 @@ import {confirmDialog} from "../dialog/confirmDialog"; import {setPadding} from "../protyle/ui/initUI"; import {reloadProtyle} from "../protyle/util/reload"; import {updateHotkeyTip} from "../protyle/util/compatibility"; +import {App} from "../index"; export const editor = { element: undefined as Element, @@ -257,7 +258,7 @@ export const editor = { `; }, - bindEvent: () => { + bindEvent: (app: App) => { const fontFamilyElement = editor.element.querySelector("#fontFamily") as HTMLSelectElement; if (fontFamilyElement.tagName === "SELECT") { let fontFamilyHTML = ``; @@ -317,7 +318,7 @@ export const editor = { fontFamily: fontFamilyElement.value, emoji: window.siyuan.config.editor.emoji }, response => { - editor.onSetEditor(response.data); + editor.onSetEditor(response.data, app); }); }; editor.element.querySelectorAll("input.b3-switch, select.b3-select, input.b3-slider").forEach((item) => { @@ -337,13 +338,13 @@ export const editor = { }); }); }, - onSetEditor: (editorData: IEditor) => { + onSetEditor: (editorData: IEditor, app: App) => { if (editorData.readOnly !== window.siyuan.config.editor.readOnly) { editor.setReadonly(editorData.readOnly); } window.siyuan.config.editor = editorData; getAllModels().editor.forEach((item) => { - reloadProtyle(item.editor.protyle, false); + reloadProtyle(item.editor.protyle, app, false); setPadding(item.editor.protyle); if (window.siyuan.config.editor.fullWidth) { item.editor.protyle.contentElement.setAttribute("data-fullwidth", "true"); diff --git a/app/src/config/index.ts b/app/src/config/index.ts index 91e68ac52..1fafd5dbf 100644 --- a/app/src/config/index.ts +++ b/app/src/config/index.ts @@ -146,6 +146,6 @@ export const openSetting = (app: App) => { }); }); editor.element = dialog.element.querySelector('.config__tab-container[data-name="editor"]'); - editor.bindEvent(); + editor.bindEvent(app); return dialog; }; diff --git a/app/src/dialog/processSystem.ts b/app/src/dialog/processSystem.ts index 5a6b49b3d..4a91f11d3 100644 --- a/app/src/dialog/processSystem.ts +++ b/app/src/dialog/processSystem.ts @@ -37,7 +37,7 @@ export const reloadSync = (app: App, data: { upsertRootIDs: string[], removeRoot if (data.removeRootIDs.includes(window.siyuan.mobile.popEditor.protyle.block.rootID)) { hideElements(["dialog"]); } else { - reloadProtyle(window.siyuan.mobile.popEditor.protyle, false); + reloadProtyle(window.siyuan.mobile.popEditor.protyle, app, false); window.siyuan.mobile.popEditor.protyle.breadcrumb.render(window.siyuan.mobile.popEditor.protyle, true); } } @@ -45,7 +45,7 @@ export const reloadSync = (app: App, data: { upsertRootIDs: string[], removeRoot if (data.removeRootIDs.includes(window.siyuan.mobile.editor.protyle.block.rootID)) { setEmpty(app); } else { - reloadProtyle(window.siyuan.mobile.editor.protyle, false); + reloadProtyle(window.siyuan.mobile.editor.protyle, app, false); fetchPost("/api/block/getDocInfo", { id: window.siyuan.mobile.editor.protyle.block.rootID }, (response) => { @@ -60,7 +60,7 @@ export const reloadSync = (app: App, data: { upsertRootIDs: string[], removeRoot const allModels = getAllModels(); allModels.editor.forEach(item => { if (data.upsertRootIDs.includes(item.editor.protyle.block.rootID)) { - reloadProtyle(item.editor.protyle, false); + reloadProtyle(item.editor.protyle, app, false); updateTitle(item.editor.protyle.block.rootID, item.parent); } else if (data.removeRootIDs.includes(item.editor.protyle.block.rootID)) { item.parent.parent.removeTab(item.parent.id, false, false, false); diff --git a/app/src/editor/util.ts b/app/src/editor/util.ts index 688c7a40b..3d1516663 100644 --- a/app/src/editor/util.ts +++ b/app/src/editor/util.ts @@ -343,7 +343,7 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod return true; } if (options.zoomIn) { - zoomOut(editor.editor.protyle, options.id); + zoomOut({app: options.app, protyle: editor.editor.protyle, id: options.id}); return true; } let nodeElement = editor.editor.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.id}"]`); @@ -353,7 +353,7 @@ const switchEditor = (editor: Editor, options: IOpenFileOptions, allModels: IMod mode: (options.action && options.action.includes(Constants.CB_GET_CONTEXT)) ? 3 : 0, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, editor.editor.protyle, options.action); + onGet({data: getResponse, protyle: editor.editor.protyle, action: options.action, app: options.app}); // 大纲点击折叠标题下的内容时,需更新反链面板 updateBacklinkGraph(allModels, editor.editor.protyle); }); diff --git a/app/src/history/diff.ts b/app/src/history/diff.ts index b5057eefe..6030c06aa 100644 --- a/app/src/history/diff.ts +++ b/app/src/history/diff.ts @@ -74,7 +74,12 @@ const renderCompare = (app: App, element: HTMLElement) => { } else { textElement.classList.add("fn__none"); leftElement.lastElementChild.classList.remove("fn__none"); - onGet(response, leftEditor.protyle, [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML]); + onGet({ + data: response, + protyle: leftEditor.protyle, + action: [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML], + app + }); } textElement.previousElementSibling.textContent = dayjs(response.data.updated).format("YYYY-MM-DD HH:mm"); }); @@ -90,7 +95,12 @@ const renderCompare = (app: App, element: HTMLElement) => { } else { textElement.classList.add("fn__none"); rightElement.lastElementChild.classList.remove("fn__none"); - onGet(response, rightEditor.protyle, [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML]); + onGet({ + data: response, + protyle: rightEditor.protyle, + action: [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML], + app + }); } textElement.previousElementSibling.textContent = dayjs(response.data.updated).format("YYYY-MM-DD HH:mm"); }); diff --git a/app/src/history/history.ts b/app/src/history/history.ts index d27b77cbd..f6498ed46 100644 --- a/app/src/history/history.ts +++ b/app/src/history/history.ts @@ -611,7 +611,12 @@ const bindEvent = (app: App, element: Element, dialog?: Dialog) => { } else { mdElement.classList.add("fn__none"); docElement.classList.remove("fn__none"); - onGet(response, historyEditor.protyle, [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML]); + onGet({ + data: response, + protyle: historyEditor.protyle, + action: [Constants.CB_GET_HISTORY, Constants.CB_GET_HTML], + app + }); } }); } diff --git a/app/src/index.ts b/app/src/index.ts index aad028677..503206771 100644 --- a/app/src/index.ts +++ b/app/src/index.ts @@ -181,7 +181,7 @@ export class App { }); setNoteBook(); initBlockPopover(this); - promiseTransactions(); + promiseTransactions(this); } } diff --git a/app/src/layout/dock/Outline.ts b/app/src/layout/dock/Outline.ts index c0e297257..5449fcdd3 100644 --- a/app/src/layout/dock/Outline.ts +++ b/app/src/layout/dock/Outline.ts @@ -156,7 +156,12 @@ export class Outline extends Model { mode: 0, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, item.editor.protyle, [Constants.CB_GET_FOCUS]); + onGet({ + data: getResponse, + protyle: item.editor.protyle, + action: [Constants.CB_GET_FOCUS], + app: options.app + }); }); } return true; diff --git a/app/src/menus/protyle.ts b/app/src/menus/protyle.ts index 233137239..9341fec8a 100644 --- a/app/src/menus/protyle.ts +++ b/app/src/menus/protyle.ts @@ -434,16 +434,30 @@ export const contentMenu = (protyle: IProtyle, nodeElement: Element) => { } }; -export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushBack = true, callback?: () => void, reload = false) => { - if (protyle.options.backlinkData) { +export const zoomOut = (options: { + app: App, + protyle: IProtyle, + id: string, + focusId?: string, + isPushBack?: boolean, + callback?: () => void, + reload?: boolean +}) => { + if (options.protyle.options.backlinkData) { return; } - const breadcrumbHLElement = protyle.breadcrumb?.element.querySelector(".protyle-breadcrumb__item--active"); - if (!reload && breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === id) { - if (id === protyle.block.rootID) { + if (typeof options.isPushBack === "undefined") { + options.isPushBack = true; + } + if (typeof options.reload === "undefined") { + options.reload = false; + } + const breadcrumbHLElement = options.protyle.breadcrumb?.element.querySelector(".protyle-breadcrumb__item--active"); + if (!options.reload && breadcrumbHLElement && breadcrumbHLElement.getAttribute("data-node-id") === options.id) { + if (options.id === options.protyle.block.rootID) { return; } - const focusElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId || id}"]`); + const focusElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId || options.id}"]`); if (focusElement) { focusBlock(focusElement); focusElement.scrollIntoView(); @@ -452,58 +466,73 @@ export const zoomOut = (protyle: IProtyle, id: string, focusId?: string, isPushB } if (window.siyuan.mobile?.editor) { window.siyuan.storage[Constants.LOCAL_DOCINFO] = { - id, - action: id === protyle.block.rootID ? [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT] : [Constants.CB_GET_ALL] + id: options.id, + action: options.id === options.protyle.block.rootID ? [Constants.CB_GET_HL, Constants.CB_GET_CONTEXT] : [Constants.CB_GET_ALL] }; setStorageVal(Constants.LOCAL_DOCINFO, window.siyuan.storage[Constants.LOCAL_DOCINFO]); - if (isPushBack) { + if (options.isPushBack) { pushBack(); } } /// #if !MOBILE - if (protyle.breadcrumb) { - protyle.breadcrumb.toggleExit(id === protyle.block.rootID); + if (options.protyle.breadcrumb) { + options.protyle.breadcrumb.toggleExit(options.id === options.protyle.block.rootID); } /// #endif fetchPost("/api/filetree/getDoc", { - id, - size: id === protyle.block.rootID ? window.siyuan.config.editor.dynamicLoadBlocks : Constants.SIZE_GET_MAX, + id: options.id, + size: options.id === options.protyle.block.rootID ? window.siyuan.config.editor.dynamicLoadBlocks : Constants.SIZE_GET_MAX, }, getResponse => { - if (isPushBack) { - onGet(getResponse, protyle, id === protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_HTML]); + if (options.isPushBack) { + onGet({ + data: getResponse, + protyle: options.protyle, + action: options.id === options.protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_HTML], + app: options.app + }); } else { - onGet(getResponse, protyle, id === protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML, Constants.CB_GET_UNUNDO] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO, Constants.CB_GET_HTML]); + onGet({ + data: getResponse, + protyle: options.protyle, + action: options.id === options.protyle.block.rootID ? [Constants.CB_GET_FOCUS, Constants.CB_GET_HTML, Constants.CB_GET_UNUNDO] : [Constants.CB_GET_ALL, Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO, Constants.CB_GET_HTML], + app: options.app + }); } // https://github.com/siyuan-note/siyuan/issues/4874 - if (focusId) { - const focusElement = protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId}"]`); + if (options.focusId) { + const focusElement = options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId}"]`); if (focusElement) { focusBlock(focusElement); focusElement.scrollIntoView(); - } else if (id === protyle.block.rootID) { // 聚焦返回后,该块是动态加载的,但是没加载出来 + } else if (options.id === options.protyle.block.rootID) { // 聚焦返回后,该块是动态加载的,但是没加载出来 fetchPost("/api/filetree/getDoc", { - id: focusId, + id: options.focusId, mode: 3, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getFocusResponse => { - onGet(getFocusResponse, protyle, isPushBack ? [Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO]); + onGet({ + data: getFocusResponse, + protyle: options.protyle, + action: options.isPushBack ? [Constants.CB_GET_FOCUS] : [Constants.CB_GET_FOCUS, Constants.CB_GET_UNUNDO], + app: options.app + }); }); return; } } /// #if !MOBILE - if (protyle.model) { + if (options.protyle.model) { const allModels = getAllModels(); allModels.outline.forEach(item => { - if (item.blockId === protyle.block.rootID) { - item.setCurrent(protyle.wysiwyg.element.querySelector(`[data-node-id="${focusId || id}"]`)); + if (item.blockId === options.protyle.block.rootID) { + item.setCurrent(options.protyle.wysiwyg.element.querySelector(`[data-node-id="${options.focusId || options.id}"]`)); } }); - updateBacklinkGraph(allModels, protyle); + updateBacklinkGraph(allModels, options.protyle); } /// #endif - if (callback) { - callback(); + if (options.callback) { + options.callback(); } }); }; diff --git a/app/src/mobile/editor.ts b/app/src/mobile/editor.ts index 0337e133f..d263403c1 100644 --- a/app/src/mobile/editor.ts +++ b/app/src/mobile/editor.ts @@ -58,7 +58,7 @@ export const openMobileFileById = (app: App, id: string, action = [Constants.CB_ size: action.includes(Constants.CB_GET_ALL) ? Constants.SIZE_GET_MAX : window.siyuan.config.editor.dynamicLoadBlocks, mode: action.includes(Constants.CB_GET_CONTEXT) ? 3 : 0, }, getResponse => { - onGet(getResponse, window.siyuan.mobile.editor.protyle, action); + onGet({data: getResponse, protyle: window.siyuan.mobile.editor.protyle, action, app}); window.siyuan.mobile.editor.protyle.breadcrumb?.render(window.siyuan.mobile.editor.protyle); }); window.siyuan.mobile.editor.protyle.undo.clear(); diff --git a/app/src/mobile/index.ts b/app/src/mobile/index.ts index ff95c2be7..216b3658f 100644 --- a/app/src/mobile/index.ts +++ b/app/src/mobile/index.ts @@ -96,13 +96,13 @@ class App { handleTouchEnd(this, event); }, false); }); - promiseTransactions(); + promiseTransactions(this); } } const siyuanApp = new App(); -window.goBack = goBack; +window.goBack = goBack.apply(siyuanApp); window.showKeyboardToolbar = (height) => { document.getElementById("keyboardToolbar").setAttribute("data-keyboardheight", (height ? height : window.innerHeight / 2 - 42).toString()); showKeyboardToolbar(); diff --git a/app/src/mobile/menu/index.ts b/app/src/mobile/menu/index.ts index 2fab5b1d5..abbc318b0 100644 --- a/app/src/mobile/menu/index.ts +++ b/app/src/mobile/menu/index.ts @@ -144,7 +144,7 @@ export const initRightMenu = (app: App) => { event.stopPropagation(); break; } else if (target.id === "menuEditor") { - initEditor(); + initEditor(app); event.preventDefault(); event.stopPropagation(); break; diff --git a/app/src/mobile/menu/search.ts b/app/src/mobile/menu/search.ts index 1d947b1d0..cf5e4b6f7 100644 --- a/app/src/mobile/menu/search.ts +++ b/app/src/mobile/menu/search.ts @@ -16,7 +16,7 @@ import {reloadProtyle} from "../../protyle/util/reload"; import {activeBlur, hideKeyboardToolbar} from "../util/keyboardToolbar"; import {App} from "../../index"; -const replace = (element: Element, config: ISearchOption, isAll: boolean) => { +const replace = (app: App,element: Element, config: ISearchOption, isAll: boolean) => { if (config.method === 1 || config.method === 2) { showMessage(window.siyuan.languages._kernel[132]); return; @@ -60,7 +60,7 @@ const replace = (element: Element, config: ISearchOption, isAll: boolean) => { if (ids.length > 1) { return; } - reloadProtyle(window.siyuan.mobile.editor.protyle, false); + reloadProtyle(window.siyuan.mobile.editor.protyle, app, false); if (currentLiElement.nextElementSibling) { currentLiElement.nextElementSibling.classList.add("b3-list-item--focus"); @@ -478,12 +478,12 @@ const initSearchEvent = (app: App, element: Element, config: ISearchOption) => { event.preventDefault(); break; } else if (type === "replace-all") { - replace(element, config, true); + replace(app, element, config, true); event.stopPropagation(); event.preventDefault(); break; } else if (type === "replace") { - replace(element, config, false); + replace(app, element, config, false); event.stopPropagation(); event.preventDefault(); break; diff --git a/app/src/mobile/settings/editor.ts b/app/src/mobile/settings/editor.ts index 89fa9968d..0cb55853f 100644 --- a/app/src/mobile/settings/editor.ts +++ b/app/src/mobile/settings/editor.ts @@ -3,8 +3,9 @@ import {fetchPost} from "../../util/fetch"; import {reloadProtyle} from "../../protyle/util/reload"; import {setInlineStyle} from "../../util/assets"; import {confirmDialog} from "../../dialog/confirmDialog"; +import {App} from "../../index"; -const setEditor = (modelMainElement: Element) => { +const setEditor = (app: App, modelMainElement: Element) => { let dynamicLoadBlocks = parseInt((modelMainElement.querySelector("#dynamicLoadBlocks") as HTMLInputElement).value); if (48 > dynamicLoadBlocks) { dynamicLoadBlocks = 48; @@ -40,12 +41,12 @@ const setEditor = (modelMainElement: Element) => { window.siyuan.config.editor.historyRetentionDays = parseInt((modelMainElement.querySelector("#historyRetentionDays") as HTMLInputElement).value); fetchPost("/api/setting/setEditor", window.siyuan.config.editor, response => { window.siyuan.config.editor = response.data; - reloadProtyle(window.siyuan.mobile.editor.protyle, false); + reloadProtyle(window.siyuan.mobile.editor.protyle, app, false); setInlineStyle(); }); }; -export const initEditor = () => { +export const initEditor = (app: App) => { openModel({ title: window.siyuan.languages.editor, icon: "iconEdit", @@ -230,12 +231,12 @@ export const initEditor = () => { modelMainElement.querySelectorAll("input.b3-switch, select.b3-select, input.b3-slider").forEach((item) => { item.addEventListener("change", () => { - setEditor(modelMainElement); + setEditor(app, modelMainElement); }); }); modelMainElement.querySelectorAll("textarea.b3-text-field, input.b3-text-field, input.b3-slider").forEach((item) => { item.addEventListener("blur", () => { - setEditor(modelMainElement); + setEditor(app, modelMainElement); }); }); modelMainElement.querySelectorAll("input.b3-slider").forEach((item) => { diff --git a/app/src/mobile/util/MobileBackFoward.ts b/app/src/mobile/util/MobileBackFoward.ts index bc7a36172..921d7918d 100644 --- a/app/src/mobile/util/MobileBackFoward.ts +++ b/app/src/mobile/util/MobileBackFoward.ts @@ -11,10 +11,11 @@ import {setStorageVal} from "../../protyle/util/compatibility"; import {closePanel} from "./closePanel"; import {showMessage} from "../../dialog/message"; import {getCurrentEditor} from "../editor"; +import {App} from "../../index"; const forwardStack: IBackStack[] = []; -const focusStack = (backStack: IBackStack) => { +const focusStack = (backStack: IBackStack, app: App) => { const protyle = getCurrentEditor().protyle; window.siyuan.storage[Constants.LOCAL_DOCINFO] = { id: backStack.id, @@ -50,8 +51,14 @@ const focusStack = (backStack: IBackStack) => { if (backStack.zoomId !== protyle.block.id) { fetchPost("/api/block/checkBlockExist", {id: backStack.id}, existResponse => { if (existResponse.data) { - zoomOut(protyle, backStack.id, undefined, false, () => { - protyle.contentElement.scrollTop = backStack.scrollTop; + zoomOut({ + app, + protyle, + id: backStack.id, + isPushBack: false, + callback: () => { + protyle.contentElement.scrollTop = backStack.scrollTop; + } }); } }); @@ -104,7 +111,7 @@ export const pushBack = () => { }); }; -export const goForward = () => { +export const goForward = (app: App) => { if (window.siyuan.menus.menu.element.classList.contains("b3-menu--fullscreen") && !window.siyuan.menus.menu.element.classList.contains("fn__none")) { window.siyuan.menus.menu.element.dispatchEvent(new CustomEvent("click", {detail: "back"})); @@ -123,10 +130,10 @@ export const goForward = () => { return; } window.siyuan.backStack.push(forwardStack.pop()); - focusStack(forwardStack[forwardStack.length - 1]); + focusStack(forwardStack[forwardStack.length - 1], app); }; -export const goBack = () => { +export const goBack = (app: App) => { const editor = getCurrentEditor(); if (window.siyuan.menus.menu.element.classList.contains("b3-menu--fullscreen") && !window.siyuan.menus.menu.element.classList.contains("fn__none")) { @@ -174,5 +181,5 @@ export const goBack = () => { } const item = window.siyuan.backStack.pop(); forwardStack.push(item); - focusStack(item); + focusStack(item, app); }; diff --git a/app/src/mobile/util/initFramework.ts b/app/src/mobile/util/initFramework.ts index 053aaad5c..f0cc14c05 100644 --- a/app/src/mobile/util/initFramework.ts +++ b/app/src/mobile/util/initFramework.ts @@ -23,7 +23,7 @@ import {App} from "../../index"; export const initFramework = (app: App) => { setInlineStyle(); renderSnippet(); - initKeyboardToolbar(); + initKeyboardToolbar(app); const sidebarElement = document.getElementById("sidebar"); let outline: MobileOutline; let backlink: MobileBacklinks; diff --git a/app/src/mobile/util/keyboardToolbar.ts b/app/src/mobile/util/keyboardToolbar.ts index 28e298c76..e89092097 100644 --- a/app/src/mobile/util/keyboardToolbar.ts +++ b/app/src/mobile/util/keyboardToolbar.ts @@ -4,6 +4,7 @@ import {moveToDown, moveToUp} from "../../protyle/wysiwyg/move"; import {Constants} from "../../constants"; import {focusByRange, getSelectionPosition} from "../../protyle/util/selection"; import {getCurrentEditor} from "../editor"; +import {App} from "../../index"; let renderKeyboardToolbarTimeout: number; let showUtil = false; @@ -327,7 +328,7 @@ export const activeBlur = () => { (document.activeElement as HTMLElement).blur(); }; -export const initKeyboardToolbar = () => { +export const initKeyboardToolbar = (app: App) => { let preventRender = false; document.addEventListener("selectionchange", () => { if (!preventRender) { @@ -416,10 +417,10 @@ export const initKeyboardToolbar = () => { return; } if (type === "undo") { - protyle.undo.undo(protyle); + protyle.undo.undo(app, protyle); return; } else if (type === "redo") { - protyle.undo.redo(protyle); + protyle.undo.redo(app, protyle); return; } if (getSelection().rangeCount === 0) { @@ -475,7 +476,7 @@ export const initKeyboardToolbar = () => { } return; } else if (type === "more") { - protyle.breadcrumb.showMenu(protyle, { + protyle.breadcrumb.showMenu(app, protyle, { x: 0, y: 0 }); diff --git a/app/src/protyle/breadcrumb/action.ts b/app/src/protyle/breadcrumb/action.ts index 218d69c61..dbec1e7e5 100644 --- a/app/src/protyle/breadcrumb/action.ts +++ b/app/src/protyle/breadcrumb/action.ts @@ -7,8 +7,9 @@ import {Constants} from "../../constants"; import {hideAllElements, hideElements} from "../ui/hideElements"; import {hasClosestByClassName} from "../util/hasClosest"; import {reloadProtyle} from "../util/reload"; +import {App} from "../../index"; -export const netImg2LocalAssets = (protyle: IProtyle) => { +export const netImg2LocalAssets = (protyle: IProtyle, app: App) => { if (protyle.element.querySelector(".wysiwygLoading")) { return; } @@ -18,11 +19,11 @@ export const netImg2LocalAssets = (protyle: IProtyle) => { id: protyle.block.rootID }, () => { /// #if MOBILE - reloadProtyle(protyle, false); + reloadProtyle(protyle, app, false); /// #else getAllModels().editor.forEach(item => { if (item.editor.protyle.block.rootID === protyle.block.rootID) { - reloadProtyle(item.editor.protyle, item.editor.protyle.element.isSameNode(protyle.element)); + reloadProtyle(item.editor.protyle, app, item.editor.protyle.element.isSameNode(protyle.element)); } }); /// #endif diff --git a/app/src/protyle/breadcrumb/index.ts b/app/src/protyle/breadcrumb/index.ts index b442646a2..f983d8a3f 100644 --- a/app/src/protyle/breadcrumb/index.ts +++ b/app/src/protyle/breadcrumb/index.ts @@ -57,25 +57,25 @@ export class Breadcrumb { }); /// #endif } else { - zoomOut(protyle, id); + zoomOut({protyle, id, app}); } event.preventDefault(); break; } else if (target.getAttribute("data-menu") === "true") { - this.showMenu(protyle, { + this.showMenu(app, protyle, { x: event.clientX, y: event.clientY }); event.preventDefault(); break; } else if (target.getAttribute("data-type") === "exit-focus") { - zoomOut(protyle, protyle.block.rootID, protyle.block.id); + zoomOut({protyle, id: protyle.block.rootID, focusId: protyle.block.id, app}); event.preventDefault(); break; } else if (target.getAttribute("data-type") === "context") { event.preventDefault(); if (target.classList.contains("block__icon--active")) { - zoomOut(protyle, protyle.options.blockId); + zoomOut({protyle, id: protyle.options.blockId, app}); target.classList.remove("block__icon--active"); } else { fetchPost("/api/filetree/getDoc", { @@ -83,7 +83,7 @@ export class Breadcrumb { mode: 3, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_HL]); + onGet({data: getResponse, protyle, action: [Constants.CB_GET_HL], app}); this.toggleExit(true); }); target.classList.add("block__icon--active"); @@ -158,7 +158,7 @@ export class Breadcrumb { } } - public showMenu(protyle: IProtyle, position: { x: number, y: number }) { + public showMenu(app: App, protyle: IProtyle, position: { x: number, y: number }) { let id; const cursorNodeElement = hasClosestBlock(getEditorRange(protyle.element).startContainer); if (cursorNodeElement) { @@ -260,7 +260,7 @@ export class Breadcrumb { icon: "iconTransform", accelerator: window.siyuan.config.keymap.editor.general.netImg2LocalAsset.custom, click() { - netImg2LocalAssets(protyle); + netImg2LocalAssets(protyle, app); } }).element); window.siyuan.menus.menu.append(new MenuItem({ @@ -303,7 +303,7 @@ export class Breadcrumb { accelerator: window.siyuan.config.keymap.editor.general.refresh.custom, label: window.siyuan.languages.refresh, click: () => { - reloadProtyle(protyle, !isMobile()); + reloadProtyle(protyle, app, !isMobile()); } }).element); window.siyuan.menus.menu.append(new MenuItem({ diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 574b198fc..3dd7dc7a1 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -164,7 +164,7 @@ export class Gutter { return; } if (event.ctrlKey || event.metaKey) { - zoomOut(protyle, id); + zoomOut({protyle, id, app}); } else if (event.altKey) { let foldElement: Element; Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${id}"]`)).find(item => { @@ -648,7 +648,7 @@ export class Gutter { }); writeText(protyle.lute.BlockDOM2StdMd(html).trimEnd()); protyle.breadcrumb?.hide(); - removeBlock(protyle, selectsElement[0], getEditorRange(selectsElement[0])); + removeBlock(this.app, protyle, selectsElement[0], getEditorRange(selectsElement[0])); } else { focusByRange(getEditorRange(selectsElement[0])); document.execCommand("cut"); @@ -661,7 +661,7 @@ export class Gutter { icon: "iconMove", click: () => { movePathTo((toPath) => { - hintMoveBlock(toPath[0], selectsElement, protyle); + hintMoveBlock(toPath[0], selectsElement, protyle, this.app); }); } }).element); @@ -671,7 +671,7 @@ export class Gutter { accelerator: "⌫", click: () => { protyle.breadcrumb?.hide(); - removeBlock(protyle, selectsElement[0], getEditorRange(selectsElement[0])); + removeBlock(this.app, protyle, selectsElement[0], getEditorRange(selectsElement[0])); } }).element); @@ -1078,7 +1078,7 @@ export class Gutter { click: () => { if (isNotEditBlock(nodeElement)) { writeText(protyle.lute.BlockDOM2StdMd(removeEmbed(nodeElement)).trimEnd()); - removeBlock(protyle, nodeElement, getEditorRange(nodeElement)); + removeBlock(this.app, protyle, nodeElement, getEditorRange(nodeElement)); protyle.breadcrumb?.hide(); } else { focusByRange(getEditorRange(nodeElement)); @@ -1092,7 +1092,7 @@ export class Gutter { icon: "iconMove", click: () => { movePathTo((toPath) => { - hintMoveBlock(toPath[0], [nodeElement], protyle); + hintMoveBlock(toPath[0], [nodeElement], protyle, this.app); }); } }).element); @@ -1102,7 +1102,7 @@ export class Gutter { accelerator: "⌫", click: () => { protyle.breadcrumb?.hide(); - removeBlock(protyle, nodeElement, getEditorRange(nodeElement)); + removeBlock(this.app, protyle, nodeElement, getEditorRange(nodeElement)); } }).element); } @@ -1401,8 +1401,8 @@ export class Gutter { window.siyuan.menus.menu.append(new MenuItem({ accelerator: `${updateHotkeyTip(window.siyuan.config.keymap.general.enter.custom)}/${updateHotkeyTip("⌘Click")}`, label: window.siyuan.languages.enter, - click() { - zoomOut(protyle, id); + click:()=> { + zoomOut({protyle, id, app: this.app}); } }).element); window.siyuan.menus.menu.append(new MenuItem({ @@ -1423,7 +1423,7 @@ export class Gutter { /// #endif } } else { - zoomOut(protyle, protyle.block.parent2ID, id); + zoomOut({protyle, id:protyle.block.parent2ID, focusId:id, app: this.app}); } } }).element); diff --git a/app/src/protyle/hint/extend.ts b/app/src/protyle/hint/extend.ts index 3999db04e..5e902a620 100644 --- a/app/src/protyle/hint/extend.ts +++ b/app/src/protyle/hint/extend.ts @@ -19,6 +19,7 @@ import {zoomOut} from "../../menus/protyle"; import {hideElements} from "../ui/hideElements"; import {genAssetHTML} from "../../asset/renderAssets"; import {unicode2Emoji} from "../../emoji"; +import {App} from "../../index"; export const hintSlash = (key: string, protyle: IProtyle) => { const allList: IHintData[] = [{ @@ -461,7 +462,7 @@ export const hintRenderAssets = (value: string, protyle: IProtyle) => { hideElements(["util"], protyle); }; -export const hintMoveBlock = (pathString: string, sourceElements: Element[], protyle: IProtyle) => { +export const hintMoveBlock = (pathString: string, sourceElements: Element[], protyle: IProtyle, app: App) => { if (pathString === "/") { return; } @@ -512,7 +513,7 @@ export const hintMoveBlock = (pathString: string, sourceElements: Element[], pro }); } else if (protyle.block.showAll && parentElement.classList.contains("protyle-wysiwyg") && parentElement.childElementCount === 0) { setTimeout(() => { - zoomOut(protyle, protyle.block.parent2ID, protyle.block.parent2ID); + zoomOut({app, protyle, id: protyle.block.parent2ID, focusId:protyle.block.parent2ID}); }, Constants.TIMEOUT_INPUT * 2 + 100); } else if (parentElement.classList.contains("protyle-wysiwyg") && parentElement.innerHTML === "" && !hasClosestByClassName(parentElement, "block__edit", true) && diff --git a/app/src/protyle/index.ts b/app/src/protyle/index.ts index d715357c0..63d989fea 100644 --- a/app/src/protyle/index.ts +++ b/app/src/protyle/index.ts @@ -77,7 +77,7 @@ export class Protyle { this.protyle.undo = new Undo(); this.protyle.wysiwyg = new WYSIWYG(app, this.protyle); this.protyle.toolbar = new Toolbar(app, this.protyle); - this.protyle.scroll = new Scroll(this.protyle); // 不能使用 render.scroll 来判读是否初始化,除非重构后面用到的相关变量 + this.protyle.scroll = new Scroll(this.protyle, this.app); // 不能使用 render.scroll 来判读是否初始化,除非重构后面用到的相关变量 if (this.protyle.options.render.gutter) { this.protyle.gutter = new Gutter(app, this.protyle); } @@ -95,7 +95,7 @@ export class Protyle { switch (data.cmd) { case "reload": if (data.data === this.protyle.block.rootID) { - reloadProtyle(this.protyle, false); + reloadProtyle(this.protyle, app, false); } break; case "addLoading": @@ -105,7 +105,7 @@ export class Protyle { break; case "transactions": data.data[0].doOperations.forEach((item: IOperation) => { - onTransaction(this.protyle, item, false); + onTransaction(app, this.protyle, item, false); }); break; case "readonly": @@ -123,10 +123,10 @@ export class Protyle { id: this.protyle.block.rootID, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, this.protyle); + onGet({data: getResponse, protyle: this.protyle, app: this.app}); }); } else { - reloadProtyle(this.protyle, false); + reloadProtyle(this.protyle, app, false); } /// #if !MOBILE if (data.cmd === "heading2doc") { @@ -224,6 +224,7 @@ export class Protyle { if (scrollObj) { scrollObj.rootId = response.data.rootID; getDocByScroll({ + app: this.app, protyle: this.protyle, scrollAttr: scrollObj, mergedOptions, @@ -237,6 +238,7 @@ export class Protyle { }); } else { getDocByScroll({ + app: this.app, protyle: this.protyle, scrollAttr: options.scrollAttr, mergedOptions, @@ -260,7 +262,7 @@ export class Protyle { mode: (mergedOptions.action && mergedOptions.action.includes(Constants.CB_GET_CONTEXT)) ? 3 : 0, size: mergedOptions.action?.includes(Constants.CB_GET_ALL) ? Constants.SIZE_GET_MAX : window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, this.protyle, mergedOptions.action); + onGet({data: getResponse, protyle: this.protyle, app: this.app, action: mergedOptions.action}); this.afterOnGet(mergedOptions); }); } @@ -330,7 +332,7 @@ export class Protyle { this.protyle.preview = new Preview(this.app, this.protyle); - initUI(this.protyle); + initUI(this.protyle, this.app); } /** 聚焦到编辑器 */ diff --git a/app/src/protyle/scroll/event.ts b/app/src/protyle/scroll/event.ts index b8f9b7b9f..163bc2a20 100644 --- a/app/src/protyle/scroll/event.ts +++ b/app/src/protyle/scroll/event.ts @@ -4,9 +4,10 @@ import {fetchPost} from "../../util/fetch"; import {onGet} from "../util/onGet"; import {isMobile} from "../../util/functions"; import {hasClosestBlock, hasClosestByClassName} from "../util/hasClosest"; +import {App} from "../../index"; let getIndexTimeout: number; -export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => { +export const scrollEvent = (app: App, protyle: IProtyle, element: HTMLElement) => { let elementRect = element.getBoundingClientRect(); element.addEventListener("scroll", () => { if (!protyle.toolbar.element.classList.contains("fn__none")) { @@ -70,7 +71,12 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => { }, getResponse => { protyle.contentElement.style.overflow = ""; protyle.contentElement.style.width = ""; - onGet(getResponse, protyle, [Constants.CB_GET_BEFORE, Constants.CB_GET_UNCHANGEID]); + onGet({ + data: getResponse, + protyle, + action: [Constants.CB_GET_BEFORE, Constants.CB_GET_UNCHANGEID], + app + }); }); } } else if ((element.scrollTop > element.scrollHeight - element.clientHeight * 1.8) && @@ -82,7 +88,12 @@ export const scrollEvent = (protyle: IProtyle, element: HTMLElement) => { mode: 2, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]); + onGet({ + data: getResponse, + protyle, + action: [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID], + app + }); }); } protyle.scroll.lastScrollTop = Math.max(element.scrollTop, 0); diff --git a/app/src/protyle/scroll/index.ts b/app/src/protyle/scroll/index.ts index 41169d3dd..87f7a77a2 100644 --- a/app/src/protyle/scroll/index.ts +++ b/app/src/protyle/scroll/index.ts @@ -5,6 +5,7 @@ import {updateHotkeyTip} from "../util/compatibility"; import {hasClosestByClassName} from "../util/hasClosest"; import {goEnd, goHome} from "../wysiwyg/commonHotkey"; import {isMobile} from "../../util/functions"; +import {App} from "../../index"; export class Scroll { public element: HTMLElement; @@ -13,7 +14,7 @@ export class Scroll { public lastScrollTop: number; public keepLazyLoad: boolean; // 保持加载内容 - constructor(protyle: IProtyle) { + constructor(protyle: IProtyle, app: App) { this.parentElement = document.createElement("div"); this.parentElement.classList.add("protyle-scroll"); if (!isMobile()) { @@ -41,25 +42,25 @@ export class Scroll { }); /// #if BROWSER this.inputElement.addEventListener("change", () => { - this.setIndex(protyle); + this.setIndex(protyle, app); }); this.inputElement.addEventListener("touchend", () => { - this.setIndex(protyle); + this.setIndex(protyle, app); }); /// #endif this.parentElement.addEventListener("click", (event) => { const target = event.target as HTMLElement; if (hasClosestByClassName(target, "protyle-scroll__up")) { - goHome(protyle); + goHome(protyle, app); } else if (hasClosestByClassName(target, "protyle-scroll__down")) { - goEnd(protyle); + goEnd(protyle, app); } else if (target.classList.contains("b3-slider")) { - this.setIndex(protyle); + this.setIndex(protyle, app); } }); } - private setIndex(protyle: IProtyle) { + private setIndex(protyle: IProtyle, app: App) { if (protyle.wysiwyg.element.getAttribute("data-top")) { return; } @@ -70,7 +71,12 @@ export class Scroll { mode: 0, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_FOCUSFIRST, Constants.CB_GET_UNCHANGEID]); + onGet({ + data: getResponse, + protyle, + action: [Constants.CB_GET_FOCUSFIRST, Constants.CB_GET_UNCHANGEID], + app + }); }); } diff --git a/app/src/protyle/scroll/saveScroll.ts b/app/src/protyle/scroll/saveScroll.ts index 1b24df733..3d5f7c13d 100644 --- a/app/src/protyle/scroll/saveScroll.ts +++ b/app/src/protyle/scroll/saveScroll.ts @@ -3,6 +3,7 @@ import {getSelectionOffset} from "../util/selection"; import {fetchPost} from "../../util/fetch"; import {onGet} from "../util/onGet"; import {Constants} from "../../constants"; +import {App} from "../../index"; export const saveScroll = (protyle: IProtyle, getObject = false) => { if (!protyle.wysiwyg.element.firstElementChild || window.siyuan.config.readonly) { @@ -45,6 +46,7 @@ export const saveScroll = (protyle: IProtyle, getObject = false) => { }; export const getDocByScroll = (options: { + app: App, protyle: IProtyle, scrollAttr: IScrollAttr, mergedOptions?: IOptions, @@ -68,7 +70,13 @@ export const getDocByScroll = (options: { }, response => { actions.push(Constants.CB_GET_ALL); options.protyle.breadcrumb?.toggleExit(false); - onGet(response, options.protyle, actions, options.scrollAttr); + onGet({ + data: response, + protyle: options.protyle, + action: actions, + scrollAttr: options.scrollAttr, + app: options.app + }); if (options.cb) { options.cb(); } @@ -81,7 +89,13 @@ export const getDocByScroll = (options: { endID: options.scrollAttr.endId, }, response => { options.protyle.breadcrumb?.toggleExit(true); - onGet(response, options.protyle, actions, options.scrollAttr); + onGet({ + data: response, + protyle: options.protyle, + action: actions, + scrollAttr: options.scrollAttr, + app: options.app + }); if (options.cb) { options.cb(); } diff --git a/app/src/protyle/ui/initUI.ts b/app/src/protyle/ui/initUI.ts index 9264ab561..ed00f9235 100644 --- a/app/src/protyle/ui/initUI.ts +++ b/app/src/protyle/ui/initUI.ts @@ -7,8 +7,9 @@ import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest"; import {isMac} from "../util/compatibility"; import {setInlineStyle} from "../../util/assets"; import {fetchPost} from "../../util/fetch"; +import {App} from "../../index"; -export const initUI = (protyle: IProtyle) => { +export const initUI = (protyle: IProtyle, app: App) => { protyle.contentElement = document.createElement("div"); protyle.contentElement.className = "protyle-content"; if (window.siyuan.config.editor.fullWidth) { @@ -24,7 +25,7 @@ export const initUI = (protyle: IProtyle) => { } protyle.contentElement.appendChild(protyle.wysiwyg.element); if (!protyle.options.action.includes(Constants.CB_GET_HISTORY)) { - scrollEvent(protyle, protyle.contentElement); + scrollEvent(app, protyle, protyle.contentElement); } protyle.element.append(protyle.contentElement); protyle.element.appendChild(protyle.preview.element); diff --git a/app/src/protyle/undo/index.ts b/app/src/protyle/undo/index.ts index 8cda95be2..128016f4e 100644 --- a/app/src/protyle/undo/index.ts +++ b/app/src/protyle/undo/index.ts @@ -7,6 +7,7 @@ import {scrollCenter} from "../../util/highlightById"; import {getCurrentWindow} from "@electron/remote"; /// #endif import {matchHotKey} from "../util/hotKey"; +import {App} from "../../index"; interface IOperations { doOperations: IOperation[], @@ -23,7 +24,7 @@ export class Undo { this.undoStack = []; } - public undo(protyle: IProtyle) { + public undo(app: App, protyle: IProtyle) { if (protyle.disabled) { return; } @@ -31,13 +32,13 @@ export class Undo { return; } const state = this.undoStack.pop(); - this.render(protyle, state, false); + this.render(app, protyle, state, false); this.hasUndo = true; this.redoStack.push(state); } - public redo(protyle: IProtyle) { + public redo(app: App, protyle: IProtyle) { if (protyle.disabled) { return; } @@ -45,21 +46,21 @@ export class Undo { return; } const state = this.redoStack.pop(); - this.render(protyle, state, true); + this.render(app, protyle, state, true); this.undoStack.push(state); } - private render(protyle: IProtyle, state: IOperations, redo: boolean) { + private render(app: App, protyle: IProtyle, state: IOperations, redo: boolean) { hideElements(["hint", "gutter"], protyle); protyle.wysiwyg.lastHTMLs = {}; if (!redo) { state.undoOperations.forEach(item => { - onTransaction(protyle, item, true); + onTransaction(app, protyle, item, true); }); transaction(protyle, state.undoOperations); } else { state.doOperations.forEach(item => { - onTransaction(protyle, item, true); + onTransaction(app, protyle, item, true); }); transaction(protyle, state.doOperations); } diff --git a/app/src/protyle/util/editorCommonEvent.ts b/app/src/protyle/util/editorCommonEvent.ts index cd3521fb4..06dd875f2 100644 --- a/app/src/protyle/util/editorCommonEvent.ts +++ b/app/src/protyle/util/editorCommonEvent.ts @@ -19,6 +19,7 @@ import {uploadLocalFiles} from "../upload"; import {insertHTML} from "./insertHTML"; import {isBrowser} from "../../util/functions"; import {hideElements} from "../ui/hideElements"; +import {App} from "../../index"; const moveToNew = (protyle: IProtyle, sourceElements: Element[], targetElement: Element, newSourceElement: Element, isSameDoc: boolean, isBottom: boolean, isCopy: boolean) => { @@ -695,7 +696,7 @@ const dragSame = async (protyle: IProtyle, sourceElements: Element[], targetElem focusBlock(sourceElements[0]); }; -export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { +export const dropEvent = (app: App, protyle: IProtyle, editorElement: HTMLElement) => { editorElement.addEventListener("dragstart", (event) => { const target = event.target as HTMLElement; if (target.tagName === "IMG") { @@ -852,7 +853,7 @@ export const dropEvent = (protyle: IProtyle, editorElement: HTMLElement) => { id: protyle.block.id, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle); + onGet({data: getResponse, protyle, app}); /// #if !MOBILE // 文档标题互转后,需更新大纲 updatePanelByEditor({ diff --git a/app/src/protyle/util/onGet.ts b/app/src/protyle/util/onGet.ts index edef270e7..7d6d92660 100644 --- a/app/src/protyle/util/onGet.ts +++ b/app/src/protyle/util/onGet.ts @@ -16,84 +16,94 @@ import {removeLoading} from "../ui/initUI"; import {isMobile} from "../../util/functions"; import {foldPassiveType} from "../wysiwyg/renderBacklink"; import {showMessage} from "../../dialog/message"; +import {App} from "../../index"; -export const onGet = (data: IWebSocketData, protyle: IProtyle, action: string[] = [], scrollAttr?: IScrollAttr) => { - protyle.wysiwyg.element.removeAttribute("data-top"); - if (data.code === 1) { +export const onGet = (options: { + data: IWebSocketData, + protyle: IProtyle, + action?: string[], + scrollAttr?: IScrollAttr + app: App +}) => { + if (!options.action) { + options.action = []; + } + options.protyle.wysiwyg.element.removeAttribute("data-top"); + if (options.data.code === 1) { // 其他报错 - if (protyle.model) { - protyle.model.parent.parent.removeTab(protyle.model.parent.id, false, false); + if (options.protyle.model) { + options.protyle.model.parent.parent.removeTab(options.protyle.model.parent.id, false, false); } else { - protyle.element.innerHTML = `
${window.siyuan.languages.refExpired}
`; + options.protyle.element.innerHTML = `
${window.siyuan.languages.refExpired}
`; } return; } - if (data.code === 3) { + if (options.data.code === 3) { // block not found return; } - protyle.notebookId = data.data.box; - protyle.path = data.data.path; + options.protyle.notebookId = options.data.data.box; + options.protyle.path = options.data.data.path; - if (data.data.eof && !scrollAttr) { - if (action.includes(Constants.CB_GET_BEFORE)) { - protyle.wysiwyg.element.firstElementChild.setAttribute("data-eof", "1"); + if (options.data.data.eof && !options.scrollAttr) { + if (options.action.includes(Constants.CB_GET_BEFORE)) { + options.protyle.wysiwyg.element.firstElementChild.setAttribute("data-eof", "1"); } else { - protyle.wysiwyg.element.lastElementChild.setAttribute("data-eof", "2"); + options.protyle.wysiwyg.element.lastElementChild.setAttribute("data-eof", "2"); } - if (data.data.mode !== 4) { + if (options.data.data.mode !== 4) { return; } } - hideElements(["gutter"], protyle); - protyle.block.parentID = data.data.parentID; - protyle.block.parent2ID = data.data.parent2ID; - protyle.block.rootID = data.data.rootID; - protyle.block.showAll = false; - protyle.block.mode = data.data.mode; - protyle.block.blockCount = data.data.blockCount; - protyle.block.scroll = data.data.scroll; - protyle.block.action = action; - if (!action.includes(Constants.CB_GET_UNCHANGEID)) { - protyle.block.id = data.data.id; // 非缩放情况时不一定是 rootID(搜索打开页签);缩放时必为缩放 id,否则需查看代码 - protyle.scroll.lastScrollTop = 0; - protyle.contentElement.scrollTop = 0; - protyle.wysiwyg.element.setAttribute("data-doc-type", data.data.type); + hideElements(["gutter"], options.protyle); + options.protyle.block.parentID = options.data.data.parentID; + options.protyle.block.parent2ID = options.data.data.parent2ID; + options.protyle.block.rootID = options.data.data.rootID; + options.protyle.block.showAll = false; + options.protyle.block.mode = options.data.data.mode; + options.protyle.block.blockCount = options.data.data.blockCount; + options.protyle.block.scroll = options.data.data.scroll; + options.protyle.block.action = options.action; + if (!options.action.includes(Constants.CB_GET_UNCHANGEID)) { + options.protyle.block.id = options.data.data.id; // 非缩放情况时不一定是 rootID(搜索打开页签);缩放时必为缩放 id,否则需查看代码 + options.protyle.scroll.lastScrollTop = 0; + options.protyle.contentElement.scrollTop = 0; + options.protyle.wysiwyg.element.setAttribute("data-doc-type", options.data.data.type); } // 防止动态加载加载过多的内容 - if (action.includes(Constants.CB_GET_APPEND) || action.includes(Constants.CB_GET_BEFORE) || action.includes(Constants.CB_GET_HTML)) { + if (options.action.includes(Constants.CB_GET_APPEND) || options.action.includes(Constants.CB_GET_BEFORE) || options.action.includes(Constants.CB_GET_HTML)) { setHTML({ - content: data.data.content, - expand: data.data.isBacklinkExpand, - action, - scrollAttr, - isSyncing: data.data.isSyncing, - }, protyle); - removeLoading(protyle); + content: options.data.data.content, + expand: options.data.data.isBacklinkExpand, + action: options.action, + scrollAttr: options.scrollAttr, + isSyncing: options.data.data.isSyncing, + }, options.protyle, options.app); + removeLoading(options.protyle); return; } fetchPost("/api/block/getDocInfo", { - id: protyle.block.rootID + id: options.protyle.block.rootID }, (response) => { - if (protyle.options.render.title) { + if (options.protyle.options.render.title) { // 页签没有打开 - protyle.title.render(protyle, response); - } else if (protyle.options.render.background) { - protyle.background.render(response.data.ial, protyle.block.rootID); - protyle.wysiwyg.renderCustom(response.data.ial); + options.protyle.title.render(options.protyle, response); + } else if (options.protyle.options.render.background) { + options.protyle.background.render(response.data.ial, options.protyle.block.rootID); + options.protyle.wysiwyg.renderCustom(response.data.ial); } setHTML({ - content: data.data.content, - expand: data.data.isBacklinkExpand, - action, - scrollAttr, - isSyncing: data.data.isSyncing, - }, protyle); + content: options.data.data.content, + expand: options.data.data.isBacklinkExpand, + action: options.action, + scrollAttr: options.scrollAttr, + isSyncing: options.data.data.isSyncing, + }, options.protyle, options.app); setTitle(response.data.ial.title); - removeLoading(protyle); + removeLoading(options.protyle); }); }; @@ -103,7 +113,7 @@ const setHTML = (options: { isSyncing: boolean, expand: boolean, scrollAttr?: IScrollAttr -}, protyle: IProtyle) => { +}, protyle: IProtyle, app: App) => { if (protyle.contentElement.classList.contains("fn__none")) { return; } @@ -251,7 +261,7 @@ const setHTML = (options: { mode: 2, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]); + onGet({data: getResponse, protyle, action: [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID], app}); }); } if (options.action.includes(Constants.CB_GET_APPEND) || options.action.includes(Constants.CB_GET_BEFORE)) { diff --git a/app/src/protyle/util/reload.ts b/app/src/protyle/util/reload.ts index f1c3e4378..90c07bd44 100644 --- a/app/src/protyle/util/reload.ts +++ b/app/src/protyle/util/reload.ts @@ -4,8 +4,9 @@ import {getDocByScroll, saveScroll} from "../scroll/saveScroll"; import {renderBacklink} from "../wysiwyg/renderBacklink"; import {hasClosestByClassName} from "./hasClosest"; import {preventScroll} from "../scroll/preventScroll"; +import {App} from "../../index"; -export const reloadProtyle = (protyle: IProtyle, focus: boolean) => { +export const reloadProtyle = (protyle: IProtyle, app: App, focus: boolean) => { if (window.siyuan.config.editor.displayBookmarkIcon) { protyle.wysiwyg.element.classList.add("protyle-wysiwyg--attr"); } else { @@ -39,6 +40,7 @@ export const reloadProtyle = (protyle: IProtyle, focus: boolean) => { } else { preventScroll(protyle); getDocByScroll({ + app, protyle, focus, scrollAttr: saveScroll(protyle, true) diff --git a/app/src/protyle/wysiwyg/commonHotkey.ts b/app/src/protyle/wysiwyg/commonHotkey.ts index a436f3704..f4f180698 100644 --- a/app/src/protyle/wysiwyg/commonHotkey.ts +++ b/app/src/protyle/wysiwyg/commonHotkey.ts @@ -36,7 +36,7 @@ export const commonHotkey = (app: App, protyle: IProtyle, event: KeyboardEvent) } if (matchHotKey(window.siyuan.config.keymap.editor.general.netImg2LocalAsset.custom, event)) { - netImg2LocalAssets(protyle); + netImg2LocalAssets(protyle, app); event.preventDefault(); event.stopPropagation(); return true; @@ -228,7 +228,7 @@ export const duplicateBlock = (nodeElements: Element[], protyle: IProtyle) => { scrollCenter(protyle); }; -export const goHome = (protyle: IProtyle) => { +export const goHome = (protyle: IProtyle, app: App) => { if (protyle.wysiwyg.element.firstElementChild.getAttribute("data-node-index") === "0" || protyle.wysiwyg.element.firstElementChild.getAttribute("data-eof") === "1" || protyle.options.backlinkData) { @@ -241,12 +241,12 @@ export const goHome = (protyle: IProtyle) => { mode: 0, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]); + onGet({data: getResponse, protyle, action: [Constants.CB_GET_FOCUS], app}); }); } }; -export const goEnd = (protyle: IProtyle) => { +export const goEnd = (protyle: IProtyle, app: App) => { if (!protyle.scroll.element.classList.contains("fn__none") && protyle.wysiwyg.element.lastElementChild.getAttribute("data-eof") !== "2") { fetchPost("/api/filetree/getDoc", { @@ -254,7 +254,7 @@ export const goEnd = (protyle: IProtyle) => { mode: 4, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_FOCUS]); + onGet({data: getResponse, protyle, action: [Constants.CB_GET_FOCUS], app}); }); } else { protyle.contentElement.scrollTop = protyle.contentElement.scrollHeight; diff --git a/app/src/protyle/wysiwyg/index.ts b/app/src/protyle/wysiwyg/index.ts index 1d12b6be5..c81ab936e 100644 --- a/app/src/protyle/wysiwyg/index.ts +++ b/app/src/protyle/wysiwyg/index.ts @@ -95,7 +95,7 @@ export class WYSIWYG { } this.bindEvent(protyle); keydown(app, protyle, this.element); - dropEvent(protyle, this.element); + dropEvent(app, protyle, this.element); } public renderCustom(ial: IObject) { @@ -1025,7 +1025,7 @@ export class WYSIWYG { } } const nextElement = getNextBlock(selectElements[selectElements.length - 1]); - removeBlock(protyle, nodeElement, range); + removeBlock(this.app, protyle, nodeElement, range); if (nextElement) { // Ctrl+X 剪切后光标应跳到下一行行首 https://github.com/siyuan-note/siyuan/issues/5485 focusBlock(nextElement); @@ -1299,7 +1299,12 @@ export class WYSIWYG { size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { preventGetTopHTML = false; - onGet(getResponse, protyle, [Constants.CB_GET_BEFORE, Constants.CB_GET_UNCHANGEID]); + onGet({ + data: getResponse, + protyle, + action: [Constants.CB_GET_BEFORE, Constants.CB_GET_UNCHANGEID], + app: this.app + }); }); preventGetTopHTML = true; } @@ -1860,7 +1865,7 @@ export class WYSIWYG { } else if (event.shiftKey) { openAttr(actionElement.parentElement, protyle); } else if (ctrlIsPressed) { - zoomOut(protyle, actionElement.parentElement.getAttribute("data-node-id")); + zoomOut({protyle, id: actionElement.parentElement.getAttribute("data-node-id"), app: this.app}); } else { if (actionElement.classList.contains("protyle-action--task")) { const html = actionElement.parentElement.outerHTML; diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 8b64e9ea6..ba6180450 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -431,7 +431,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) topNodeElement.nextElementSibling?.classList.contains("list") && topNodeElement.previousElementSibling.classList.contains("protyle-action")) { topNodeElement = topNodeElement.parentElement; } - zoomOut(protyle, topNodeElement.getAttribute("data-node-id")); + zoomOut({protyle, id:topNodeElement.getAttribute("data-node-id"), app}); event.preventDefault(); event.stopPropagation(); return; @@ -448,7 +448,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) }); } } else { - zoomOut(protyle, protyle.block.parent2ID, nodeElement.getAttribute("data-node-id")); + zoomOut({protyle, id:protyle.block.parent2ID, focusId:nodeElement.getAttribute("data-node-id"), app}); } event.preventDefault(); event.stopPropagation(); @@ -477,14 +477,14 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) } // ctrl+home 光标移动到顶 if (!event.altKey && !event.shiftKey && isCtrl(event) && event.key === "Home") { - goHome(protyle); + goHome(protyle, app); event.stopPropagation(); event.preventDefault(); return; } // ctrl+end 光标移动到尾 if (!event.altKey && !event.shiftKey && isCtrl(event) && event.key === "End") { - goEnd(protyle); + goEnd(protyle, app); event.stopPropagation(); event.preventDefault(); return; @@ -694,7 +694,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) // 不可使用 !event.shiftKey,否则 https://ld246.com/article/1666434796806 if (!event.altKey && (event.key === "Backspace" || event.key === "Delete")) { if (protyle.wysiwyg.element.querySelector(".protyle-wysiwyg--select")) { - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -736,7 +736,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) previousSibling.nodeType !== 3 && (previousSibling as HTMLElement).outerHTML === "\\" && !hasPreviousSibling(previousSibling.parentElement)) { range.setStartBefore(previousSibling.parentElement); - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -746,7 +746,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) range.startContainer.parentElement.getAttribute("data-type")?.indexOf("backslash") > -1 && !hasPreviousSibling(range.startContainer.parentElement)) { range.setStartBefore(range.startContainer.parentElement); - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -768,7 +768,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) const editElement = getContenteditableElement(nodeElement); if (!editElement) { nodeElement.classList.add("protyle-wysiwyg--select"); - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -783,7 +783,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) if (nextRange) { const nextBlockElement = hasClosestBlock(nextRange.startContainer); if (nextBlockElement) { - removeBlock(protyle, nextBlockElement, nextRange); + removeBlock(app, protyle, nextBlockElement, nextRange); } } event.stopPropagation(); @@ -801,7 +801,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) range.startOffset === 0 || (currentNode && currentNode.nodeType === 3 && !hasPreviousSibling(currentNode) && currentNode.textContent === "") // https://ld246.com/article/1649251218696 )) { - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -810,7 +810,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) nodeElement.getAttribute("data-type") === "NodeTable" && (range.startContainer as HTMLElement).children[range.startOffset - 1]?.tagName === "TABLE") { nodeElement.classList.add("protyle-wysiwyg--select"); - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); event.stopPropagation(); event.preventDefault(); return; @@ -927,14 +927,14 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) } if (matchHotKey(window.siyuan.config.keymap.editor.general.undo.custom, event)) { - protyle.undo.undo(protyle); + protyle.undo.undo(app, protyle); event.preventDefault(); event.stopPropagation(); return; } if (matchHotKey(window.siyuan.config.keymap.editor.general.redo.custom, event)) { - protyle.undo.redo(protyle); + protyle.undo.redo(app, protyle); event.preventDefault(); event.stopPropagation(); return; @@ -1446,7 +1446,7 @@ export const keydown = (app: App, protyle: IProtyle, editorElement: HTMLElement) }); writeText(protyle.lute.BlockDOM2StdMd(html).trimEnd()); const nextElement = getNextBlock(selectElements[selectElements.length - 1]); - removeBlock(protyle, nodeElement, range); + removeBlock(app, protyle, nodeElement, range); if (nextElement) { focusBlock(nextElement); } diff --git a/app/src/protyle/wysiwyg/remove.ts b/app/src/protyle/wysiwyg/remove.ts index 8979aef12..d204a8e6f 100644 --- a/app/src/protyle/wysiwyg/remove.ts +++ b/app/src/protyle/wysiwyg/remove.ts @@ -15,6 +15,7 @@ import {preventScroll} from "../scroll/preventScroll"; import {hideElements} from "../ui/hideElements"; import {Constants} from "../../constants"; import {scrollCenter} from "../../util/highlightById"; +import {App} from "../../index"; const removeLi = (protyle: IProtyle, blockElement: Element, range: Range) => { if (!blockElement.parentElement.previousElementSibling && blockElement.parentElement.nextElementSibling && blockElement.parentElement.nextElementSibling.classList.contains("protyle-attr")) { @@ -177,7 +178,7 @@ const removeLi = (protyle: IProtyle, blockElement: Element, range: Range) => { focusByWbr(previousLastElement.parentElement, range); }; -export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Range) => { +export const removeBlock = (app: App, protyle: IProtyle, blockElement: Element, range: Range) => { // 删除后,防止滚动条滚动后调用 get 请求,因为返回的请求已查找不到内容块了 preventScroll(protyle); const selectElements = Array.from(protyle.wysiwyg.element.querySelectorAll(".protyle-wysiwyg--select")); @@ -241,7 +242,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran if (sideElement) { if (protyle.block.showAll && sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0) { setTimeout(() => { - zoomOut(protyle, protyle.block.parent2ID, protyle.block.parent2ID); + zoomOut({app, protyle, id:protyle.block.parent2ID, focusId:protyle.block.parent2ID}); }, Constants.TIMEOUT_INPUT * 2 + 100); } else { if ((sideElement.classList.contains("protyle-wysiwyg") && protyle.wysiwyg.element.childElementCount === 0)) { @@ -294,7 +295,7 @@ export const removeBlock = (protyle: IProtyle, blockElement: Element, range: Ran // 空代码块直接删除 if (blockElement.getAttribute("data-type") === "NodeCodeBlock" && getContenteditableElement(blockElement).textContent.trim() === "") { blockElement.classList.add("protyle-wysiwyg--select"); - removeBlock(protyle, blockElement, range); + removeBlock(app, protyle, blockElement, range); return; } // 设置 bq 和代码块光标 diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 315536489..3b0938adb 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -17,6 +17,7 @@ import {hideElements} from "../ui/hideElements"; import {reloadProtyle} from "../util/reload"; import {countBlockWord} from "../../layout/status"; import {needSubscribe} from "../../util/needSubscribe"; +import {App} from "../../index"; const removeTopElement = (updateElement: Element, protyle: IProtyle) => { // 移动到其他文档中,该块需移除 @@ -48,7 +49,7 @@ const removeTopElement = (updateElement: Element, protyle: IProtyle) => { }; // 用于执行操作,外加处理当前编辑器中引用块、嵌入块的更新 -const promiseTransaction = () => { +const promiseTransaction = (app: App) => { const protyle = window.siyuan.transactions[0].protyle; const doOperations = window.siyuan.transactions[0].doOperations; const undoOperations = window.siyuan.transactions[0].undoOperations; @@ -64,9 +65,9 @@ const promiseTransaction = () => { }] }, (response) => { if (window.siyuan.transactions.length === 0) { - promiseTransactions(); + promiseTransactions(app); } else { - promiseTransaction(); + promiseTransaction(app); } countBlockWord([], protyle.block.rootID, true); @@ -135,7 +136,12 @@ const promiseTransaction = () => { mode: 2, size: window.siyuan.config.editor.dynamicLoadBlocks, }, getResponse => { - onGet(getResponse, protyle, [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID]); + onGet({ + data: getResponse, + protyle, + action: [Constants.CB_GET_APPEND, Constants.CB_GET_UNCHANGEID], + app + }); }); } return; @@ -306,18 +312,18 @@ const updateEmbed = (protyle: IProtyle, operation: IOperation) => { } }; -export const promiseTransactions = () => { +export const promiseTransactions = (app: App) => { window.siyuan.transactionsTimeout = window.setInterval(() => { if (window.siyuan.transactions.length === 0) { return; } window.clearInterval(window.siyuan.transactionsTimeout); - promiseTransaction(); + promiseTransaction(app); }, Constants.TIMEOUT_INPUT * 2); }; // 用于推送和撤销 -export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: boolean) => { +export const onTransaction = (app: App, protyle: IProtyle, operation: IOperation, focus: boolean) => { const updateElements: Element[] = []; Array.from(protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${operation.id}"]`)).forEach(item => { if (!hasClosestByAttribute(item.parentElement, "data-type", "NodeBlockQueryEmbed")) { @@ -649,7 +655,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, focus: b return; } if (operation.action === "append") { - reloadProtyle(protyle, false); + reloadProtyle(protyle, app, false); } }; diff --git a/app/src/search/util.ts b/app/src/search/util.ts index 3aba83d5e..29e20b5bf 100644 --- a/app/src/search/util.ts +++ b/app/src/search/util.ts @@ -271,7 +271,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (type === "next") { if (!target.getAttribute("disabled")) { config.page++; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); } event.stopPropagation(); event.preventDefault(); @@ -279,7 +279,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } else if (type === "previous") { if (!target.getAttribute("disabled")) { config.page--; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); } event.stopPropagation(); event.preventDefault(); @@ -288,7 +288,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo config.removed = false; criteriaData.find(item => { if (item.name === target.innerText.trim()) { - updateConfig(element, item, config, edit); + updateConfig(element, item, config, edit, app); return true; } }); @@ -319,7 +319,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo config.page = 1; searchPathInputElement.innerHTML = config.hPath; searchPathInputElement.setAttribute("title", ""); - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); const includeElement = element.querySelector("#searchInclude"); includeElement.classList.remove("b3-button--cancel"); includeElement.setAttribute("disabled", "disabled"); @@ -375,7 +375,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } else { includeElement.setAttribute("disabled", "disabled"); } - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); }); }, [], undefined, window.siyuan.languages.specifyPath); event.stopPropagation(); @@ -397,7 +397,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo }); } config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); event.stopPropagation(); event.preventDefault(); break; @@ -419,14 +419,14 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); break; } else if (target.id === "searchRefresh") { - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); event.stopPropagation(); event.preventDefault(); break; } else if (target.id === "searchMore") { moreMenu(config, criteriaData, element, () => { config.page = 1; - inputEvent(element, config, undefined, edit); + inputEvent(element, config, undefined, edit, app); }, () => { updateConfig(element, { removed: true, @@ -453,7 +453,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo paragraph: window.siyuan.config.search.paragraph, embedBlock: window.siyuan.config.search.embedBlock, } - }, config, edit); + }, config, edit, app); }, () => { const localData = window.siyuan.storage[Constants.LOCAL_SEARCHKEYS]; const isPopover = hasClosestByClassName(element, "b3-dialog__container"); @@ -513,7 +513,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo } else if (target.id === "searchFilter") { filterMenu(config, () => { config.page = 1; - inputEvent(element, config, undefined, edit); + inputEvent(element, config, undefined, edit, app); }); event.stopPropagation(); event.preventDefault(); @@ -522,7 +522,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo queryMenu(config, () => { element.querySelector("#searchSyntaxCheck").setAttribute("aria-label", getQueryTip(config.method)); config.page = 1; - inputEvent(element, config, undefined, edit); + inputEvent(element, config, undefined, edit, app); }); window.siyuan.menus.menu.popup({x: event.clientX - 16, y: event.clientY - 16}, true); event.stopPropagation(); @@ -577,12 +577,12 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo event.preventDefault(); return; } else if (target.id === "replaceAllBtn") { - replace(element, config, edit, true); + replace(element, config, edit, app, true); event.stopPropagation(); event.preventDefault(); break; } else if (target.id === "replaceBtn") { - replace(element, config, edit, false); + replace(element, config, edit, app, false); event.stopPropagation(); event.preventDefault(); break; @@ -596,7 +596,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (target.parentElement.id === "searchHistoryList") { searchInputElement.value = target.textContent; config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); } else if (target.parentElement.id === "replaceHistoryList") { replaceInputElement.value = target.textContent; replaceHistoryElement.classList.add("fn__none"); @@ -627,6 +627,7 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo id: target.getAttribute("data-node-id"), config, value: searchInputElement.value, + app, }); searchInputElement.focus(); } else if (target.classList.contains("b3-list-item--focus")) { @@ -670,11 +671,11 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo searchInputElement.addEventListener("compositionend", (event: InputEvent) => { config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit, event); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app, event); }); searchInputElement.addEventListener("input", (event: InputEvent) => { config.page = 1; - inputTimeout = inputEvent(element, config, inputTimeout, edit, event); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app, event); }); searchInputElement.addEventListener("blur", () => { if (config.removed) { @@ -743,7 +744,8 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo id: currentList.getAttribute("data-node-id"), config, value: searchInputElement.value, - edit + edit, + app }); event.preventDefault(); } else if (event.key === "ArrowUp") { @@ -770,7 +772,8 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo id: currentList.getAttribute("data-node-id"), config, value: searchInputElement.value, - edit + edit, + app }); event.preventDefault(); } @@ -779,10 +782,10 @@ export const genSearch = (app: App, config: ISearchOption, element: Element, clo if (event.isComposing || event.key !== "Enter") { return; } - replace(element, config, edit, false); + replace(element, config, edit, app, false); event.preventDefault(); }); - inputTimeout = inputEvent(element, config, inputTimeout, edit); + inputTimeout = inputEvent(element, config, inputTimeout, edit, app); return edit; }; @@ -805,7 +808,7 @@ const getQueryTip = (method: number) => { return methodTip; }; -const updateConfig = (element: Element, item: ISearchOption, config: ISearchOption, edit: Protyle) => { +const updateConfig = (element: Element, item: ISearchOption, config: ISearchOption, edit: Protyle, app: App) => { const dialogElement = hasClosestByClassName(element, "b3-dialog--open"); if (dialogElement && dialogElement.getAttribute("data-key") === window.siyuan.config.keymap.general.search.custom) { // https://github.com/siyuan-note/siyuan/issues/6828 @@ -861,7 +864,7 @@ const updateConfig = (element: Element, item: ISearchOption, config: ISearchOpti Object.assign(config, item); window.siyuan.storage[Constants.LOCAL_SEARCHDATA] = Object.assign({}, config); setStorageVal(Constants.LOCAL_SEARCHDATA, window.siyuan.storage[Constants.LOCAL_SEARCHDATA]); - inputEvent(element, config, undefined, edit); + inputEvent(element, config, undefined, edit, app); window.siyuan.menus.menu.remove(); }; @@ -894,6 +897,7 @@ const getArticle = (options: { config: ISearchOption, edit: Protyle value: string, + app: App }) => { fetchPost("/api/block/checkBlockFold", {id: options.id}, (foldResponse) => { options.edit.protyle.scroll.lastScrollTop = 0; @@ -907,7 +911,12 @@ const getArticle = (options: { size: foldResponse.data ? Constants.SIZE_GET_MAX : window.siyuan.config.editor.dynamicLoadBlocks, zoom: foldResponse.data, }, getResponse => { - onGet(getResponse, options.edit.protyle, foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_HL, Constants.CB_GET_HTML]); + onGet({ + data: getResponse, + protyle: options.edit.protyle, + action: foldResponse.data ? [Constants.CB_GET_ALL, Constants.CB_GET_HTML] : [Constants.CB_GET_HL, Constants.CB_GET_HTML], + app: options.app + }); const matchElement = options.edit.protyle.wysiwyg.element.querySelector(`div[data-node-id="${options.id}"] span[data-type~="search-mark"]`); if (matchElement) { matchElement.classList.add("search-mark--hl"); @@ -919,7 +928,7 @@ const getArticle = (options: { }); }; -const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: boolean) => { +const replace = (element: Element, config: ISearchOption, edit: Protyle, app: App, isAll: boolean) => { if (config.method === 1 || config.method === 2) { showMessage(window.siyuan.languages._kernel[132]); return; @@ -966,7 +975,7 @@ const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: } getAllModels().editor.forEach(item => { if (rootIds[0] === item.editor.protyle.block.rootID) { - reloadProtyle(item.editor.protyle, false); + reloadProtyle(item.editor.protyle, app, false); } }); if (currentList.nextElementSibling) { @@ -1006,11 +1015,12 @@ const replace = (element: Element, config: ISearchOption, edit: Protyle, isAll: id: currentList.getAttribute("data-node-id"), config, value: searchInputElement.value, + app, }); }); }; -const inputEvent = (element: Element, config: ISearchOption, inputTimeout: number, edit: Protyle, event?: InputEvent) => { +const inputEvent = (element: Element, config: ISearchOption, inputTimeout: number, edit: Protyle, app: App, event?: InputEvent) => { if (event && event.isComposing) { return; } @@ -1025,7 +1035,7 @@ const inputEvent = (element: Element, config: ISearchOption, inputTimeout: numbe const nextElement = element.querySelector('[data-type="next"]'); if (inputValue === "" && (!config.idPath || config.idPath.length === 0)) { fetchPost("/api/block/getRecentUpdatedBlocks", {}, (response) => { - onSearch(response.data, edit, element, config); + onSearch(response.data, edit, app, element, config); loadingElement.classList.add("fn__none"); element.querySelector("#searchResult").innerHTML = ""; previousElement.setAttribute("disabled", "true"); @@ -1054,7 +1064,7 @@ const inputEvent = (element: Element, config: ISearchOption, inputTimeout: numbe } else { nextElement.setAttribute("disabled", "disabled"); } - onSearch(response.data.blocks, edit, element, config); + onSearch(response.data.blocks, edit, app, element, config); element.querySelector("#searchResult").innerHTML = `${config.page}/${response.data.pageCount || 1} ${window.siyuan.languages.findInDoc.replace("${x}", response.data.matchedRootCount).replace("${y}", response.data.matchedBlockCount)}`; loadingElement.classList.add("fn__none"); @@ -1064,7 +1074,7 @@ const inputEvent = (element: Element, config: ISearchOption, inputTimeout: numbe return inputTimeout; }; -const onSearch = (data: IBlock[], edit: Protyle, element: Element, config: ISearchOption) => { +const onSearch = (data: IBlock[], edit: Protyle, app: App, element: Element, config: ISearchOption) => { let resultHTML = ""; data.forEach((item, index) => { const title = getNotebookName(item.box) + getDisplayName(item.hPath, false); @@ -1104,6 +1114,7 @@ ${unicode2Emoji(item.ial.icon, false, "b3-list-item__graphic", true)} id: data[0].children[0].id, config, value: searchInputElement.value, + app, }); } else { getArticle({ @@ -1111,6 +1122,7 @@ ${unicode2Emoji(item.ial.icon, false, "b3-list-item__graphic", true)} id: data[0].id, config, value: searchInputElement.value, + app }); } } else { diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index d601e2b83..ce1fe0ab6 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -49,7 +49,7 @@ interface Window { Protyle: import("../protyle/method").default - goBack(): void + goBack(app: import("../index").App): void showKeyboardToolbar(height: number): void diff --git a/app/src/util/backForward.ts b/app/src/util/backForward.ts index f65d14187..884eec68d 100644 --- a/app/src/util/backForward.ts +++ b/app/src/util/backForward.ts @@ -152,23 +152,29 @@ const focusStack = async (app: App, stack: IBackStack) => { } return false; } - zoomOut(stack.protyle, stack.zoomId || stack.protyle.block.rootID, undefined, false, () => { - Array.from(stack.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${stack.id}"]`)).find((item: HTMLElement) => { - if (!hasClosestByAttribute(item, "data-type", "NodeBlockQueryEmbed")) { - blockElement = item; - return true; + zoomOut({ + app, + protyle: stack.protyle, + id: stack.zoomId || stack.protyle.block.rootID, + isPushBack: false, + callback: () => { + Array.from(stack.protyle.wysiwyg.element.querySelectorAll(`[data-node-id="${stack.id}"]`)).find((item: HTMLElement) => { + if (!hasClosestByAttribute(item, "data-type", "NodeBlockQueryEmbed")) { + blockElement = item; + return true; + } + }); + if (!blockElement) { + return; } - }); - if (!blockElement) { - return; + getAllModels().outline.forEach(item => { + if (item.blockId === stack.protyle.block.rootID) { + item.setCurrent(blockElement); + } + }); + focusByOffset(getContenteditableElement(blockElement), stack.position.start, stack.position.end); + scrollCenter(stack.protyle, blockElement, true); } - getAllModels().outline.forEach(item => { - if (item.blockId === stack.protyle.block.rootID) { - item.setCurrent(blockElement); - } - }); - focusByOffset(getContenteditableElement(blockElement), stack.position.start, stack.position.end); - scrollCenter(stack.protyle, blockElement, true); }); return true; } diff --git a/app/src/window/index.ts b/app/src/window/index.ts index 8d6b312b7..6195ea25a 100644 --- a/app/src/window/index.ts +++ b/app/src/window/index.ts @@ -145,7 +145,7 @@ class App { }); setNoteBook(); initBlockPopover(this); - promiseTransactions(); + promiseTransactions(this); } }