[release-2.17] fix: list items require multiple backspace presses to delete (#6410)

This is an automated cherry-pick of #6408

/assign JohnNiang

```release-note
修复默认编辑器中列表项需要按多次退格键才可以删除的问题
```
release-2.17
Halo Dev Bot 2024-07-29 21:25:54 +08:00 committed by GitHub
parent 4bb7353f14
commit 256ef913b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 51 additions and 14 deletions

View File

@ -7,6 +7,7 @@ import {
type KeyboardShortcutCommand,
} from "@/tiptap";
import { TextSelection, Transaction } from "@/tiptap/pm";
import { isListActive } from "@/utils/isListActive";
declare module "@/tiptap" {
interface Commands<ReturnType> {
@ -195,14 +196,6 @@ const isTextIndent = (tr: Transaction, currNodePos: number) => {
return false;
};
const isListActive = (editor: CoreEditor) => {
return (
editor.isActive("bulletList") ||
editor.isActive("orderedList") ||
editor.isActive("taskList")
);
};
const isFilterActive = (editor: CoreEditor) => {
return editor.isActive("table") || editor.isActive("columns");
};

View File

@ -2,6 +2,7 @@ import ToolbarItem from "@/components/toolbar/ToolbarItem.vue";
import ToolbarSubItem from "@/components/toolbar/ToolbarSubItem.vue";
import { i18n } from "@/locales";
import {
CoreEditor,
EditorState,
ResolvedPos,
TextSelection,
@ -11,6 +12,7 @@ import {
} from "@/tiptap";
import type { ExtensionOptions, ToolbarItem as TypeToolbarItem } from "@/types";
import { deleteNodeByPos } from "@/utils";
import { isListActive } from "@/utils/isListActive";
import { isEmpty } from "@/utils/isNodeEmpty";
import type { ParagraphOptions } from "@tiptap/extension-paragraph";
import TiptapParagraph from "@tiptap/extension-paragraph";
@ -97,15 +99,15 @@ const Paragraph = TiptapParagraph.extend<ExtensionOptions & ParagraphOptions>({
addKeyboardShortcuts() {
return {
Backspace: ({ editor }) => {
Backspace: ({ editor }: { editor: CoreEditor }) => {
const { state, view } = editor;
const { selection } = state;
if (
!isActive(state, Paragraph.name) ||
!(selection instanceof TextSelection) ||
!selection.empty
) {
if (isListActive(editor) || !isActive(state, Paragraph.name)) {
return false;
}
if (!(selection instanceof TextSelection) || !selection.empty) {
return false;
}

View File

@ -0,0 +1,42 @@
import {
callOrReturn,
CoreEditor,
getExtensionField,
isActive,
type NodeConfig,
} from "@/tiptap";
/**
* Check if a list is active
*
* @param state - The state of the editor
* @returns Whether a list is active
* @example
* ```ts
* const isActive = isListActive(editor.state);
* ```
**/
export const isListActive = (editor: CoreEditor) => {
const extensions = editor.extensionManager.extensions;
const listExtensions = extensions.filter((extension) => {
const context = {
name: extension.name,
options: extension.options,
storage: extension.storage,
};
const group = callOrReturn(
getExtensionField<NodeConfig["group"]>(extension, "group", context)
);
if (typeof group !== "string") {
return false;
}
return group.split(" ").includes("list");
});
return listExtensions.some((extension) => {
return isActive(editor.state, extension.name);
});
};