diff --git a/app/src/block/util.ts b/app/src/block/util.ts index 9977e273a..165e6f795 100644 --- a/app/src/block/util.ts +++ b/app/src/block/util.ts @@ -8,7 +8,7 @@ import {Constants} from "../constants"; import {hideElements} from "../protyle/ui/hideElements"; import {blockRender} from "../protyle/render/blockRender"; import {fetchPost} from "../util/fetch"; -import {zoomOut} from "../menus/protyle"; +import {openFileById} from "../editor/util"; export const cancelSB = (protyle: IProtyle, nodeElement: Element) => { const doOperations: IOperation[] = []; @@ -74,25 +74,18 @@ export const genSBElement = (layout: string, id?: string, attrHTML?: string) => return sbElement; }; -export const jumpToParentNext = (protyle: IProtyle, nodeElement: Element) => { - const topElement = getTopAloneElement(nodeElement); - if (topElement) { - const topParentElement = hasClosestByClassName(topElement, "list") || hasClosestByClassName(topElement, "bq") || hasClosestByClassName(topElement, "sb") || topElement; - const nextElement = getNextBlock(topParentElement); - if (nextElement) { - focusBlock(nextElement); - scrollCenter(protyle, nextElement); - } else { - fetchPost("/api/block/getParentNextChildID", {id: nodeElement.getAttribute("data-node-id")}, (response) => { - if (response.data.id) { - zoomOut({ - protyle, - id: response.data.id, - }); - } - }); +export const jumpToParent = (protyle: IProtyle, nodeElement: Element, type: "parent" | "next" | "previous") => { + fetchPost("/api/block/getBlockSiblingID", {id: nodeElement.getAttribute("data-node-id")}, (response) => { + const targetId = response.data[type]; + if (!targetId) { + return; } - } + openFileById({ + app: protyle.app, + id: targetId, + action: [Constants.CB_GET_FOCUS] + }) + }); }; export const insertEmptyBlock = (protyle: IProtyle, position: InsertPosition, id?: string) => { diff --git a/app/src/constants.ts b/app/src/constants.ts index ba67cee7c..32dc19967 100644 --- a/app/src/constants.ts +++ b/app/src/constants.ts @@ -399,6 +399,8 @@ export abstract class Constants { insertBefore: {default: "⇧⌘B", custom: "⇧⌘B"}, insertAfter: {default: "⇧⌘A", custom: "⇧⌘A"}, jumpToParentNext: {default: "⇧⌘N", custom: "⇧⌘N"}, + jumpToParentPrev: {default: "⇧⌘M", custom: "⇧⌘M"}, + jumpToParent: {default: "⇧⌘J", custom: "⇧⌘J"}, moveToUp: {default: "⇧⌘↑", custom: "⇧⌘↑"}, moveToDown: {default: "⇧⌘↓", custom: "⇧⌘↓"} }, diff --git a/app/src/protyle/gutter/index.ts b/app/src/protyle/gutter/index.ts index 269d9d0b8..7d2316f57 100644 --- a/app/src/protyle/gutter/index.ts +++ b/app/src/protyle/gutter/index.ts @@ -28,7 +28,13 @@ import {removeEmbed} from "../wysiwyg/removeEmbed"; import {getContenteditableElement, getTopAloneElement, isNotEditBlock} from "../wysiwyg/getBlock"; import * as dayjs from "dayjs"; import {fetchPost, fetchSyncPost} from "../../util/fetch"; -import {cancelSB, genEmptyElement, getLangByType, insertEmptyBlock, jumpToParentNext} from "../../block/util"; +import { + cancelSB, + genEmptyElement, + getLangByType, + insertEmptyBlock, + jumpToParent, +} from "../../block/util"; import {countBlockWord} from "../../layout/status"; import {Constants} from "../../constants"; import {mathRender} from "../render/mathRender"; @@ -1630,9 +1636,26 @@ export class Gutter { accelerator: window.siyuan.config.keymap.editor.general.jumpToParentNext.custom, click() { hideElements(["select"], protyle); - jumpToParentNext(protyle, nodeElement); + jumpToParent(protyle, nodeElement, "next"); } }).element); + window.siyuan.menus.menu.append(new MenuItem({ + label: window.siyuan.languages.jumpToParentPrev, + accelerator: window.siyuan.config.keymap.editor.general.jumpToParentPrev.custom, + click() { + hideElements(["select"], protyle); + jumpToParent(protyle, nodeElement, "previous"); + } + }).element); + window.siyuan.menus.menu.append(new MenuItem({ + label: window.siyuan.languages.jumpToParent, + accelerator: window.siyuan.config.keymap.editor.general.jumpToParent.custom, + click() { + hideElements(["select"], protyle); + jumpToParent(protyle, nodeElement, "parent"); + } + }).element); + window.siyuan.menus.menu.append(new MenuItem({type: "separator"}).element); if (type !== "NodeThematicBreak") { diff --git a/app/src/protyle/wysiwyg/keydown.ts b/app/src/protyle/wysiwyg/keydown.ts index 6d8bf7c16..181cc6b74 100644 --- a/app/src/protyle/wysiwyg/keydown.ts +++ b/app/src/protyle/wysiwyg/keydown.ts @@ -35,7 +35,7 @@ import {turnsIntoOneTransaction, turnsIntoTransaction, updateBatchTransaction, u import {fontEvent} from "../toolbar/Font"; import {addSubList, listIndent, listOutdent} from "./list"; import {newFileContentBySelect, rename, replaceFileName} from "../../editor/rename"; -import {insertEmptyBlock, jumpToParentNext} from "../../block/util"; +import {insertEmptyBlock, jumpToParent} from "../../block/util"; import {isLocalPath} from "../../util/pathName"; /// #if !MOBILE import {openBy, openFileById, openLink} from "../../editor/util"; @@ -1358,7 +1358,19 @@ export const keydown = (protyle: IProtyle, editorElement: HTMLElement) => { return true; } if (matchHotKey(window.siyuan.config.keymap.editor.general.jumpToParentNext.custom, event)) { - jumpToParentNext(protyle, nodeElement); + jumpToParent(protyle, nodeElement, "next"); + event.preventDefault(); + event.stopPropagation(); + return true; + } + if (matchHotKey(window.siyuan.config.keymap.editor.general.jumpToParent.custom, event)) { + jumpToParent(protyle, nodeElement, "parent"); + event.preventDefault(); + event.stopPropagation(); + return true; + } + if (matchHotKey(window.siyuan.config.keymap.editor.general.jumpToParentPrev.custom, event)) { + jumpToParent(protyle, nodeElement, "previous"); event.preventDefault(); event.stopPropagation(); return true;