mirror of
https://github.com/streetwriters/notesnook.git
synced 2026-09-01 19:49:54 +02:00
editor: add move line up/down keybinding
Signed-off-by: 01zulfi <85733202+01zulfi@users.noreply.github.com>
This commit is contained in:
@@ -9,71 +9,71 @@ The following keyboard shortcuts will help you navigate Notesnook faster.
|
||||
|
||||
### General
|
||||
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| -------------------------------------------------- | ------ | ------------- | --- |
|
||||
| Search in notes list view if editor is not focused | Ctrl F | Ctrl F | ⌘ F |
|
||||
| Settings | Ctrl , | Ctrl , | ⌘ , |
|
||||
| Keyboard shortcuts | Ctrl / | Ctrl / | ⌘ / |
|
||||
| New note | - | Ctrl N | ⌘ N |
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| --- | --- | --- | --- |
|
||||
| Search in notes list view if editor is not focused | Ctrl F | Ctrl F | ⌘ F |
|
||||
| Settings | Ctrl , | Ctrl , | ⌘ , |
|
||||
| Keyboard shortcuts | Ctrl / | Ctrl / | ⌘ / |
|
||||
| New note | - | Ctrl N | ⌘ N |
|
||||
|
||||
### Navigation
|
||||
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| ---------------- | ------------------------- | ------------- | ------- |
|
||||
| Next tab | Ctrl Alt → / Ctrl Alt ⇧ → | Ctrl tab | ⌘ tab |
|
||||
| Previous tab | Ctrl Alt ← / Ctrl Alt ⇧ ← | Ctrl ⇧ tab | ⌘ ⇧ tab |
|
||||
| Command palette | Ctrl ⇧ P | Ctrl ⇧ P | ⌘ ⇧ P |
|
||||
| Quick open | Ctrl P | Ctrl P | ⌘ P |
|
||||
| New tab | - | Ctrl T | ⌘ T |
|
||||
| Close active tab | - | Ctrl W | ⌘ W |
|
||||
| Close all tabs | - | Ctrl ⇧ W | ⌘ ⇧ W |
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| --- | --- | --- | --- |
|
||||
| Next tab | Ctrl Alt → / Ctrl Alt ⇧ → | Ctrl tab | ⌘ tab |
|
||||
| Previous tab | Ctrl Alt ← / Ctrl Alt ⇧ ← | Ctrl ⇧ tab | ⌘ ⇧ tab |
|
||||
| Command palette | Ctrl ⇧ P | Ctrl ⇧ P | ⌘ ⇧ P |
|
||||
| Quick open | Ctrl P | Ctrl P | ⌘ P |
|
||||
| New tab | - | Ctrl T | ⌘ T |
|
||||
| Close active tab | - | Ctrl W | ⌘ W |
|
||||
| Close all tabs | - | Ctrl ⇧ W | ⌘ ⇧ W |
|
||||
|
||||
### Editor
|
||||
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| ---------------------------------- | ----------------- | ----------------- | ----------- |
|
||||
| Add attachment | Ctrl ⇧ A | Ctrl ⇧ A | ⌘ ⇧ A |
|
||||
| Insert blockquote | Ctrl ⇧ B | Ctrl ⇧ B | ⌘ ⇧ B |
|
||||
| Toggle bold | Ctrl B | Ctrl B | ⌘ B |
|
||||
| Toggle bullet list | Ctrl ⇧ 8 | Ctrl ⇧ 8 | ⌘ ⇧ 8 |
|
||||
| Toggle check list | Ctrl ⇧ 9 | Ctrl ⇧ 9 | ⌘ ⇧ 9 |
|
||||
| Split list item | ↵ | ↵ | ↵ |
|
||||
| Lift list item | ⇧ Tab | ⇧ Tab | ⇧ Tab |
|
||||
| Sink list item | Ctrl ⇧ Down | Ctrl ⇧ Down | ⌘ ⇧ Down |
|
||||
| Toggle code | Ctrl E | Ctrl E | ⌘ E |
|
||||
| Toggle code block | Ctrl ⇧ C | Ctrl ⇧ C | ⌘ ⇧ C |
|
||||
| Insert date | Alt D | Alt D | ⌥ D |
|
||||
| Insert time | Alt T | Alt T | ⌥ T |
|
||||
| Insert date and time | Ctrl Alt D | Ctrl Alt D | ⌘ ⌥ D |
|
||||
| Insert date and time with timezone | Ctrl Alt Z | Ctrl Alt Z | ⌘ ⌥ Z |
|
||||
| Increase font size | Ctrl [ | Ctrl [ | ⌘ [ |
|
||||
| Decrease font size | Ctrl ] | Ctrl ] | ⌘ ] |
|
||||
| Insert paragraph | Ctrl ⇧ 0 | Ctrl ⇧ 0 | ⌘ ⇧ 0 |
|
||||
| Insert heading 1 | Ctrl Alt 1 | Ctrl Alt 1 | ⌘ ⌥ 1 |
|
||||
| Insert heading 2 | Ctrl Alt 2 | Ctrl Alt 2 | ⌘ ⌥ 2 |
|
||||
| Insert heading 3 | Ctrl Alt 3 | Ctrl Alt 3 | ⌘ ⌥ 3 |
|
||||
| Insert heading 4 | Ctrl Alt 4 | Ctrl Alt 4 | ⌘ ⌥ 4 |
|
||||
| Insert heading 5 | Ctrl Alt 5 | Ctrl Alt 5 | ⌘ ⌥ 5 |
|
||||
| Insert heading 6 | Ctrl Alt 6 | Ctrl Alt 6 | ⌘ ⌥ 6 |
|
||||
| Undo | Ctrl Z | Ctrl Z | ⌘ Z |
|
||||
| Redo | Ctrl ⇧ Z / Ctrl Y | Ctrl ⇧ Z / Ctrl Y | ⌘ ⇧ Z / ⌘ Y |
|
||||
| Add image | Ctrl ⇧ I | Ctrl ⇧ I | ⌘ ⇧ I |
|
||||
| Toggle italic | Ctrl I | Ctrl I | ⌘ I |
|
||||
| Remove formatting in selection | Ctrl \ | Ctrl \ | ⌘ \ |
|
||||
| Insert internal link | Ctrl ⇧ K | Ctrl ⇧ K | ⌘ ⇧ K |
|
||||
| Insert link | Ctrl K | Ctrl K | ⌘ K |
|
||||
| Insert math block | Ctrl ⇧ M | Ctrl ⇧ M | ⌘ ⇧ M |
|
||||
| Toggle ordered list | Ctrl ⇧ 7 | Ctrl ⇧ 7 | ⌘ ⇧ 7 |
|
||||
| Toggle outline list | Ctrl ⇧ O | Ctrl ⇧ O | ⌘ ⇧ O |
|
||||
| Toggle outline list expand | Ctrl Space | Ctrl Space | ⌘ Space |
|
||||
| Open search | Ctrl F | Ctrl F | ⌘ F |
|
||||
| Toggle strike | Ctrl ⇧ S | Ctrl ⇧ S | ⌘ ⇧ S |
|
||||
| Toggle subscript | Ctrl , | Ctrl , | ⌘ , |
|
||||
| Toggle superscript | Ctrl . | Ctrl . | ⌘ . |
|
||||
| Toggle task list | Ctrl ⇧ T | Ctrl ⇧ T | ⌘ ⇧ T |
|
||||
| Text align center | Ctrl ⇧ E | Ctrl ⇧ E | ⌘ ⇧ E |
|
||||
| Text align justify | Ctrl ⇧ J | Ctrl ⇧ J | ⌘ ⇧ J |
|
||||
| Text align left | Ctrl ⇧ L | Ctrl ⇧ L | ⌘ ⇧ L |
|
||||
| Text align right | Ctrl ⇧ R | Ctrl ⇧ R | ⌘ ⇧ R |
|
||||
| Underline | Ctrl U | Ctrl U | ⌘ U |
|
||||
| Toggle highlight | Ctrl Alt H | Ctrl Alt H | ⌘ ⌥ H |
|
||||
| Description | Web | Windows/Linux | Mac |
|
||||
| --- | --- | --- | --- |
|
||||
| Add attachment | Ctrl ⇧ A | Ctrl ⇧ A | ⌘ ⇧ A |
|
||||
| Insert blockquote | Ctrl ⇧ B | Ctrl ⇧ B | ⌘ ⇧ B |
|
||||
| Toggle bold | Ctrl B | Ctrl B | ⌘ B |
|
||||
| Toggle bullet list | Ctrl ⇧ 8 | Ctrl ⇧ 8 | ⌘ ⇧ 8 |
|
||||
| Toggle check list | Ctrl ⇧ 9 | Ctrl ⇧ 9 | ⌘ ⇧ 9 |
|
||||
| Split list item | ↵ | ↵ | ↵ |
|
||||
| Lift list item | ⇧ Tab | ⇧ Tab | ⇧ Tab |
|
||||
| Sink list item | Ctrl ⇧ Down | Ctrl ⇧ Down | ⌘ ⇧ Down |
|
||||
| Toggle code | Ctrl E | Ctrl E | ⌘ E |
|
||||
| Toggle code block | Ctrl ⇧ C | Ctrl ⇧ C | ⌘ ⇧ C |
|
||||
| Insert date | Alt D | Alt D | ⌥ D |
|
||||
| Insert time | Alt T | Alt T | ⌥ T |
|
||||
| Insert date and time | Ctrl Alt D | Ctrl Alt D | ⌘ ⌥ D |
|
||||
| Insert date and time with timezone | Ctrl Alt Z | Ctrl Alt Z | ⌘ ⌥ Z |
|
||||
| Increase font size | Ctrl [ | Ctrl [ | ⌘ [ |
|
||||
| Decrease font size | Ctrl ] | Ctrl ] | ⌘ ] |
|
||||
| Insert paragraph | Ctrl Alt 0 | Ctrl Alt 0 | ⌘ ⌥ 0 |
|
||||
| Insert heading 1 | Ctrl Alt 1 | Ctrl Alt 1 | ⌘ ⌥ 1 |
|
||||
| Insert heading 2 | Ctrl Alt 2 | Ctrl Alt 2 | ⌘ ⌥ 2 |
|
||||
| Insert heading 3 | Ctrl Alt 3 | Ctrl Alt 3 | ⌘ ⌥ 3 |
|
||||
| Insert heading 4 | Ctrl Alt 4 | Ctrl Alt 4 | ⌘ ⌥ 4 |
|
||||
| Insert heading 5 | Ctrl Alt 5 | Ctrl Alt 5 | ⌘ ⌥ 5 |
|
||||
| Insert heading 6 | Ctrl Alt 6 | Ctrl Alt 6 | ⌘ ⌥ 6 |
|
||||
| Undo | Ctrl Z | Ctrl Z | ⌘ Z |
|
||||
| Redo | Ctrl ⇧ Z / Ctrl Y | Ctrl ⇧ Z / Ctrl Y | ⌘ ⇧ Z / ⌘ Y |
|
||||
| Add image | Ctrl ⇧ I | Ctrl ⇧ I | ⌘ ⇧ I |
|
||||
| Toggle italic | Ctrl I | Ctrl I | ⌘ I |
|
||||
| Remove formatting in selection | Ctrl \ | Ctrl \ | ⌘ \ |
|
||||
| Insert internal link | Ctrl ⇧ K | Ctrl ⇧ K | ⌘ ⇧ K |
|
||||
| Insert link | Ctrl K | Ctrl K | ⌘ K |
|
||||
| Insert math block | Ctrl ⇧ M | Ctrl ⇧ M | ⌘ ⇧ M |
|
||||
| Toggle ordered list | Ctrl ⇧ 7 | Ctrl ⇧ 7 | ⌘ ⇧ 7 |
|
||||
| Toggle outline list | Ctrl ⇧ O | Ctrl ⇧ O | ⌘ ⇧ O |
|
||||
| Toggle outline list expand | Ctrl Space | Ctrl Space | ⌘ Space |
|
||||
| Open search | Ctrl F | Ctrl F | ⌘ F |
|
||||
| Toggle strike | Ctrl ⇧ S | Ctrl ⇧ S | ⌘ ⇧ S |
|
||||
| Toggle subscript | Ctrl , | Ctrl , | ⌘ , |
|
||||
| Toggle superscript | Ctrl . | Ctrl . | ⌘ . |
|
||||
| Toggle task list | Ctrl ⇧ T | Ctrl ⇧ T | ⌘ ⇧ T |
|
||||
| Text align center | Ctrl ⇧ E | Ctrl ⇧ E | ⌘ ⇧ E |
|
||||
| Text align justify | Ctrl ⇧ J | Ctrl ⇧ J | ⌘ ⇧ J |
|
||||
| Text align left | Ctrl ⇧ L | Ctrl ⇧ L | ⌘ ⇧ L |
|
||||
| Text align right | Ctrl ⇧ R | Ctrl ⇧ R | ⌘ ⇧ R |
|
||||
| Underline | Ctrl U | Ctrl U | ⌘ U |
|
||||
| Toggle highlight | Ctrl Alt H | Ctrl Alt H | ⌘ ⌥ H |
|
||||
@@ -394,6 +394,18 @@ export const tiptapKeys = {
|
||||
description: "Toggle highlight",
|
||||
category: "Editor",
|
||||
type: "tiptap"
|
||||
},
|
||||
moveLineUp: {
|
||||
keys: "Alt-ArrowUp",
|
||||
description: "Move line up",
|
||||
category: "Editor",
|
||||
type: "tiptap"
|
||||
},
|
||||
moveLineDown: {
|
||||
keys: "Alt-ArrowDown",
|
||||
description: "Move line down",
|
||||
category: "Editor",
|
||||
type: "tiptap"
|
||||
}
|
||||
} satisfies Record<string, TipTapKey>;
|
||||
|
||||
@@ -451,6 +463,8 @@ export function formatKey(key: string, isMac = false, separator = " ") {
|
||||
.replace(/\bright\b/gi, "→")
|
||||
.replace(/\bleft\b/gi, "←")
|
||||
.replace(/\benter\b/gi, "↵")
|
||||
.replace(/\barrowup\b/gi, "↑")
|
||||
.replace(/\barrowdown\b/gi, "↓")
|
||||
.replace(/\b\w\b/gi, (e) => e.toUpperCase())
|
||||
.trim();
|
||||
}
|
||||
|
||||
138
packages/editor/src/extensions/key-map/__tests__/key-map.test.ts
Normal file
138
packages/editor/src/extensions/key-map/__tests__/key-map.test.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
This file is part of the Notesnook project (https://notesnook.com/)
|
||||
|
||||
Copyright (C) 2023 Streetwriters (Private) Limited
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {
|
||||
createEditor,
|
||||
h,
|
||||
p,
|
||||
outlineList,
|
||||
outlineListItem
|
||||
} from "../../../../test-utils/index.js";
|
||||
import { test, expect, describe } from "vitest";
|
||||
import { KeyMap } from "../key-map.js";
|
||||
import { OutlineList } from "../../outline-list/outline-list.js";
|
||||
import { OutlineListItem } from "../../outline-list-item/outline-list-item.js";
|
||||
|
||||
describe("key-map", () => {
|
||||
test("move paragraph up", async () => {
|
||||
const el = h("div", [p(["para 1"]), p(["para 2"]), p(["para 3"])]);
|
||||
const editorElement = h("div");
|
||||
const { editor } = createEditor({
|
||||
element: editorElement,
|
||||
initialContent: el.outerHTML,
|
||||
extensions: {
|
||||
KeyMap: KeyMap
|
||||
}
|
||||
});
|
||||
|
||||
editor.commands.setTextSelection({ from: 10, to: 10 });
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "ArrowUp",
|
||||
altKey: true
|
||||
});
|
||||
editor.view.dom.dispatchEvent(event);
|
||||
|
||||
expect(editor.getHTML()).toBe(`<p>para 2</p><p>para 1</p><p>para 3</p>`);
|
||||
});
|
||||
|
||||
test("move paragraph down", async () => {
|
||||
const el = h("div", [p(["para 1"]), p(["para 2"]), p(["para 3"])]);
|
||||
const editorElement = h("div");
|
||||
const { editor } = createEditor({
|
||||
element: editorElement,
|
||||
initialContent: el.outerHTML,
|
||||
extensions: {
|
||||
KeyMap: KeyMap
|
||||
}
|
||||
});
|
||||
|
||||
editor.commands.setTextSelection(0);
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "ArrowDown",
|
||||
altKey: true
|
||||
});
|
||||
editor.view.dom.dispatchEvent(event);
|
||||
|
||||
expect(editor.getHTML()).toBe(`<p>para 2</p><p>para 1</p><p>para 3</p>`);
|
||||
});
|
||||
|
||||
test("move outline list item up", async () => {
|
||||
const el = outlineList(
|
||||
outlineListItem(["item 1"]),
|
||||
outlineListItem(["item 2"]),
|
||||
outlineListItem(["item 3"])
|
||||
);
|
||||
const editorElement = h("div");
|
||||
const { editor } = createEditor({
|
||||
element: editorElement,
|
||||
initialContent: el.outerHTML,
|
||||
extensions: {
|
||||
KeyMap: KeyMap,
|
||||
outlineList: OutlineList,
|
||||
outlineListItem: OutlineListItem
|
||||
}
|
||||
});
|
||||
|
||||
editor.commands.setTextSelection({ from: 15, to: 15 });
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "ArrowUp",
|
||||
altKey: true
|
||||
});
|
||||
editor.view.dom.dispatchEvent(event);
|
||||
|
||||
const expectedHTML = outlineList(
|
||||
outlineListItem(["item 2"]),
|
||||
outlineListItem(["item 1"]),
|
||||
outlineListItem(["item 3"])
|
||||
).outerHTML;
|
||||
expect(editor.getHTML()).toBe(expectedHTML);
|
||||
});
|
||||
|
||||
test("move outline list item down", async () => {
|
||||
const el = outlineList(
|
||||
outlineListItem(["item 1"]),
|
||||
outlineListItem(["item 2"]),
|
||||
outlineListItem(["item 3"])
|
||||
);
|
||||
const editorElement = h("div");
|
||||
const { editor } = createEditor({
|
||||
element: editorElement,
|
||||
initialContent: el.outerHTML,
|
||||
extensions: {
|
||||
KeyMap: KeyMap,
|
||||
outlineList: OutlineList,
|
||||
outlineListItem: OutlineListItem
|
||||
}
|
||||
});
|
||||
|
||||
editor.commands.setTextSelection(0);
|
||||
const event = new KeyboardEvent("keydown", {
|
||||
key: "ArrowDown",
|
||||
altKey: true
|
||||
});
|
||||
editor.view.dom.dispatchEvent(event);
|
||||
|
||||
const expectedHTML = outlineList(
|
||||
outlineListItem(["item 2"]),
|
||||
outlineListItem(["item 1"]),
|
||||
outlineListItem(["item 3"])
|
||||
).outerHTML;
|
||||
expect(editor.getHTML()).toBe(expectedHTML);
|
||||
});
|
||||
});
|
||||
@@ -17,12 +17,17 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Extension } from "@tiptap/core";
|
||||
import { Editor, Extension } from "@tiptap/core";
|
||||
import { CodeBlock } from "../code-block/index.js";
|
||||
import { showLinkPopup } from "../../toolbar/popups/link-popup.js";
|
||||
import { isListActive } from "../../utils/list.js";
|
||||
import { tiptapKeys } from "@notesnook/common";
|
||||
import { isInTable } from "../table/prosemirror-tables/util.js";
|
||||
import { findParentNodeOfType } from "../../utils/prosemirror.js";
|
||||
import { Fragment, Node, Slice } from "@tiptap/pm/model";
|
||||
import { ReplaceStep } from "@tiptap/pm/transform";
|
||||
import { Selection } from "@tiptap/pm/state";
|
||||
import { Callout } from "../callout/callout.js";
|
||||
|
||||
export const KeyMap = Extension.create({
|
||||
name: "key-map",
|
||||
@@ -71,7 +76,122 @@ export const KeyMap = Extension.create({
|
||||
[tiptapKeys.insertLink.keys]: ({ editor }) => {
|
||||
showLinkPopup(editor);
|
||||
return true;
|
||||
},
|
||||
[tiptapKeys.moveLineUp.keys]: ({ editor }) => {
|
||||
return moveNode(editor, "up");
|
||||
},
|
||||
[tiptapKeys.moveLineDown.keys]: ({ editor }) => {
|
||||
return moveNode(editor, "down");
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
function mapChildren<T>(
|
||||
node: Node | Fragment,
|
||||
callback: (child: Node, index: number, frag: Fragment) => T
|
||||
): T[] {
|
||||
const array = [];
|
||||
for (let i = 0; i < node.childCount; i++) {
|
||||
array.push(
|
||||
callback(node.child(i), i, node instanceof Fragment ? node : node.content)
|
||||
);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
/**
|
||||
* implementation inspired from https://discuss.prosemirror.net/t/keymap-to-move-a-line/3645/5
|
||||
*/
|
||||
function moveNode(editor: Editor, dir: "up" | "down") {
|
||||
const isDown = dir === "down";
|
||||
const { state } = editor;
|
||||
if (!state.selection.empty) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { $from } = state.selection;
|
||||
|
||||
let currentResolved;
|
||||
let targetType;
|
||||
|
||||
const outlineListItem = findParentNodeOfType(
|
||||
editor.schema.nodes.outlineListItem
|
||||
)(state.selection);
|
||||
const taskItem = findParentNodeOfType(editor.schema.nodes.taskItem)(
|
||||
state.selection
|
||||
);
|
||||
const listItem = findParentNodeOfType(editor.schema.nodes.listItem)(
|
||||
state.selection
|
||||
);
|
||||
if (outlineListItem) {
|
||||
currentResolved = outlineListItem;
|
||||
targetType = editor.schema.nodes.outlineListItem;
|
||||
} else if (taskItem) {
|
||||
currentResolved = taskItem;
|
||||
targetType = editor.schema.nodes.taskItem;
|
||||
} else if (listItem) {
|
||||
currentResolved = listItem;
|
||||
targetType = editor.schema.nodes.listItem;
|
||||
} else {
|
||||
const type = $from.node().type;
|
||||
currentResolved = findParentNodeOfType(type)(state.selection);
|
||||
targetType = type;
|
||||
}
|
||||
|
||||
if (!currentResolved) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const { node: currentNode } = currentResolved;
|
||||
const parentDepth = currentResolved.depth - 1;
|
||||
const parent = $from.node(parentDepth);
|
||||
const parentPos = $from.start(parentDepth);
|
||||
|
||||
if (currentNode.type !== targetType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
(targetType === editor.schema.nodes.outlineListItem &&
|
||||
parent.type.name !== "outlineList") ||
|
||||
(targetType === editor.schema.nodes.taskItem &&
|
||||
parent.type.name !== "taskList") ||
|
||||
(targetType === editor.schema.nodes.listItem &&
|
||||
!["bulletList", "orderedList"].includes(parent.type.name))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let arr = mapChildren(parent, (node) => node);
|
||||
let index = arr.indexOf(currentNode);
|
||||
let swapWith = isDown ? index + 1 : index - 1;
|
||||
if (swapWith >= arr.length || swapWith < 0) {
|
||||
return false;
|
||||
}
|
||||
if (swapWith === 0 && parent.type.name === Callout.name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const swapWithNodeSize = arr[swapWith].nodeSize;
|
||||
|
||||
[arr[index], arr[swapWith]] = [arr[swapWith], arr[index]];
|
||||
|
||||
let tr = state.tr;
|
||||
let replaceStart = parentPos;
|
||||
let replaceEnd = $from.end(parentDepth);
|
||||
|
||||
const slice = new Slice(Fragment.fromArray(arr), 0, 0);
|
||||
|
||||
tr = tr.step(new ReplaceStep(replaceStart, replaceEnd, slice, false));
|
||||
tr = tr.setSelection(
|
||||
Selection.near(
|
||||
tr.doc.resolve(
|
||||
isDown ? $from.pos + swapWithNodeSize : $from.pos - swapWithNodeSize
|
||||
)
|
||||
)
|
||||
);
|
||||
tr.scrollIntoView();
|
||||
editor.view.dispatch(tr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user