From c918f2c803266a736a8a9c692a7b81fdacff2bd3 Mon Sep 17 00:00:00 2001 From: AirboZH Date: Tue, 2 Jan 2024 11:46:12 +0800 Subject: [PATCH] fix: Backspace does not work properly behind list (#5102) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug #### What this PR does / why we need it: 增加 `@tiptap/extension-list-keymap` 扩展,优化列表的键盘操作 #### Which issue(s) this PR fixes: Fixes #5065 #### Special notes for your reviewer: 测试方法: 1. 测试无序列表中和无序列表后对于删除键 `Delete` 和退格键 `backspace` 的支持是否符合预期 2. 测试有序列表中和有序列表后对于删除键 `Delete` 和退格键 `backspace` 的支持是否符合预期 ![2023-12-22](https://github.com/halo-dev/halo/assets/50261327/ebdc1364-bfd6-4e2f-acf0-444a03f40299) 3. 测试选择部分列表项后对于删除键 `Delete` 和退格键 `backspace` 的支持是否符合预期 4. 测试 `Ctrl-A` 全选后对于删除键 `Delete` 和退格键 `backspace` 的支持是否符合预期 ![selectAll](https://github.com/halo-dev/halo/assets/50261327/c9a69c7a-b8d7-4532-8931-16fa2bc0b41a) #### Does this PR introduce a user-facing change? ```release-note 修复无法删除有序/无序列表后空行的问题 ``` --- console/packages/editor/package.json | 1 + console/packages/editor/src/dev/App.vue | 2 + .../packages/editor/src/extensions/index.ts | 2 + .../src/extensions/list-keymap/index.ts | 48 +++++++++++++++++++ console/pnpm-lock.yaml | 11 +++++ .../src/components/editor/DefaultEditor.vue | 2 + 6 files changed, 66 insertions(+) create mode 100644 console/packages/editor/src/extensions/list-keymap/index.ts diff --git a/console/packages/editor/package.json b/console/packages/editor/package.json index abc6319cb4..5b4b43c7f7 100644 --- a/console/packages/editor/package.json +++ b/console/packages/editor/package.json @@ -61,6 +61,7 @@ "@tiptap/extension-italic": "^2.1.10", "@tiptap/extension-link": "^2.1.10", "@tiptap/extension-list-item": "^2.1.10", + "@tiptap/extension-list-keymap": "^2.1.10", "@tiptap/extension-ordered-list": "^2.1.10", "@tiptap/extension-paragraph": "^2.1.10", "@tiptap/extension-placeholder": "^2.1.10", diff --git a/console/packages/editor/src/dev/App.vue b/console/packages/editor/src/dev/App.vue index 71f0b9d43e..61c22079a4 100644 --- a/console/packages/editor/src/dev/App.vue +++ b/console/packages/editor/src/dev/App.vue @@ -43,6 +43,7 @@ import { ExtensionColumn, ExtensionNodeSelected, ExtensionTrailingNode, + ExtensionListKeymap, } from "../index"; const content = useLocalStorage("content", ""); @@ -107,6 +108,7 @@ const editor = useEditor({ ExtensionColumn, ExtensionNodeSelected, ExtensionTrailingNode, + ExtensionListKeymap, ], onUpdate: () => { content.value = editor.value?.getHTML() + ""; diff --git a/console/packages/editor/src/extensions/index.ts b/console/packages/editor/src/extensions/index.ts index f2c6bff202..17befbc9d8 100644 --- a/console/packages/editor/src/extensions/index.ts +++ b/console/packages/editor/src/extensions/index.ts @@ -13,6 +13,7 @@ import ExtensionSubscript from "./subscript"; import ExtensionBulletList from "./bullet-list"; import ExtensionOrderedList from "./ordered-list"; import ExtensionTaskList from "./task-list"; +import ExtensionListKeymap from "./list-keymap"; import ExtensionTable from "./table"; import ExtensionTextAlign from "./text-align"; import ExtensionTextStyle from "@tiptap/extension-text-style"; @@ -142,4 +143,5 @@ export { ExtensionColumn, ExtensionNodeSelected, ExtensionTrailingNode, + ExtensionListKeymap, }; diff --git a/console/packages/editor/src/extensions/list-keymap/index.ts b/console/packages/editor/src/extensions/list-keymap/index.ts new file mode 100644 index 0000000000..578afe34be --- /dev/null +++ b/console/packages/editor/src/extensions/list-keymap/index.ts @@ -0,0 +1,48 @@ +import { + listHelpers, + ListKeymap, + type ListKeymapOptions, +} from "@tiptap/extension-list-keymap"; +import { Editor } from "@tiptap/core"; + +/** + * Optimize the listKeymap extension until the issue with @tiptap/extension-list-keymap is resolved. + * https://github.com/ueberdosis/tiptap/issues/4395 + */ +const ExtensionListKeymap = ListKeymap.extend({ + addKeyboardShortcuts() { + const backspaceHandle = (editor: Editor) => { + let handled = false; + + if (!editor.state.selection.empty) { + editor.commands.deleteSelection(); + return true; + } + + this.options.listTypes.forEach( + ({ + itemName, + wrapperNames, + }: { + itemName: string; + wrapperNames: string[]; + }) => { + if (listHelpers.handleBackspace(editor, itemName, wrapperNames)) { + handled = true; + } + } + ); + + return handled; + }; + + return { + Backspace: ({ editor }: { editor: Editor }) => backspaceHandle(editor), + + "Mod-Backspace": ({ editor }: { editor: Editor }) => + backspaceHandle(editor), + }; + }, +}); + +export default ExtensionListKeymap; diff --git a/console/pnpm-lock.yaml b/console/pnpm-lock.yaml index 6bbc95deb5..4abf648565 100644 --- a/console/pnpm-lock.yaml +++ b/console/pnpm-lock.yaml @@ -496,6 +496,9 @@ importers: '@tiptap/extension-list-item': specifier: ^2.1.10 version: 2.1.11(@tiptap/core@2.1.11) + '@tiptap/extension-list-keymap': + specifier: ^2.1.10 + version: 2.1.13(@tiptap/core@2.1.11) '@tiptap/extension-ordered-list': specifier: ^2.1.10 version: 2.1.11(@tiptap/core@2.1.11) @@ -5964,6 +5967,14 @@ packages: '@tiptap/core': 2.1.11(@tiptap/pm@2.1.11) dev: false + /@tiptap/extension-list-keymap@2.1.13(@tiptap/core@2.1.11): + resolution: {integrity: sha512-D/j1aPz3tehILfUWXy9lfgoZUzxO2Jmls4hnvyGDugEBiZtQGRpqPjqhJBkkcWlxa7UnQQD2AbZ2D5P0oStx5Q==} + peerDependencies: + '@tiptap/core': ^2.0.0 + dependencies: + '@tiptap/core': 2.1.11(@tiptap/pm@2.1.11) + dev: false + /@tiptap/extension-ordered-list@2.1.11(@tiptap/core@2.1.11): resolution: {integrity: sha512-/tghfEJ5U7WFbF8xyOqRJks8KxP/lRjnroMXMglaushSMx8PYPo1dZDB/dJZw7ksy47MAaKJfKlx3gyN2CPXBQ==} peerDependencies: diff --git a/console/src/components/editor/DefaultEditor.vue b/console/src/components/editor/DefaultEditor.vue index e58d538ff6..f300f29d5b 100644 --- a/console/src/components/editor/DefaultEditor.vue +++ b/console/src/components/editor/DefaultEditor.vue @@ -48,6 +48,7 @@ import { Plugin, PluginKey, DecorationSet, + ExtensionListKeymap, } from "@halo-dev/richtext-editor"; import { IconCalendar, @@ -318,6 +319,7 @@ onMounted(() => { ]; }, }), + ExtensionListKeymap, ], autofocus: "start", onUpdate: () => {