UBERF-8080 Handle errors in ListKeymap extension (#6705)

Signed-off-by: Alexander Onnikov <Alexander.Onnikov@xored.com>
This commit is contained in:
Alexander Onnikov 2024-09-24 18:01:00 +07:00 committed by GitHub
parent 33e132cb00
commit 1ddf1fe4b0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 90 additions and 2 deletions

View File

@ -0,0 +1,88 @@
//
// Copyright © 2024 Hardcore Engineering Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
// obtain a copy of the License at https://www.eclipse.org/legal/epl-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { type Editor } from '@tiptap/core'
import ListKeymap, { type ListKeymapOptions, listHelpers } from '@tiptap/extension-list-keymap'
/**
* Workaround for the original ListKeymap extension issue that
* https://github.com/ueberdosis/tiptap/issues/4368
*/
export const ListKeymapExtension = ListKeymap.extend<ListKeymapOptions>({
addKeyboardShortcuts () {
const handleBackspace = (editor: Editor): boolean => {
let handled = false
if (!editor.state.selection.empty) {
return false
}
this.options.listTypes.forEach(({ itemName, wrapperNames }) => {
if (editor.state.schema.nodes[itemName] === undefined) {
return
}
if (listHelpers.handleBackspace(editor, itemName, wrapperNames)) {
handled = true
}
})
return handled
}
const handleDelete = (editor: Editor): boolean => {
let handled = false
if (!editor.state.selection.empty) {
return false
}
this.options.listTypes.forEach(({ itemName }) => {
if (editor.state.schema.nodes[itemName] === undefined) {
return
}
if (listHelpers.handleDelete(editor, itemName)) {
handled = true
}
})
return handled
}
const handleBackspaceSafe = (editor: Editor): boolean => {
try {
return handleBackspace(editor)
} catch (e) {
console.log(e)
return false
}
}
const handleDeleteSafe = (editor: Editor): boolean => {
try {
return handleDelete(editor)
} catch (e) {
console.log(e)
return false
}
}
return {
Backspace: ({ editor }) => handleBackspaceSafe(editor),
'Mod-Backspace': ({ editor }) => handleBackspaceSafe(editor),
Delete: ({ editor }) => handleDeleteSafe(editor),
'Mod-Delete': ({ editor }) => handleDeleteSafe(editor)
}
}
})

View File

@ -19,7 +19,6 @@ import { CodeExtension, codeOptions } from '@hcengineering/text'
import textEditor, { type ActionContext, type ExtensionCreator, type TextEditorMode } from '@hcengineering/text-editor'
import { type AnyExtension, type Editor, Extension } from '@tiptap/core'
import { type Level } from '@tiptap/extension-heading'
import ListKeymap from '@tiptap/extension-list-keymap'
import TableHeader from '@tiptap/extension-table-header'
import 'prosemirror-codemark/dist/codemark.css'
@ -30,6 +29,7 @@ import { FileExtension, type FileOptions } from '../components/extension/fileExt
import { HardBreakExtension } from '../components/extension/hardBreak'
import { ImageExtension, type ImageOptions } from '../components/extension/imageExt'
import { InlineToolbarExtension } from '../components/extension/inlineToolbar'
import { ListKeymapExtension } from '../components/extension/listkeymap'
import { NodeUuidExtension } from '../components/extension/nodeUuid'
import { ParagraphExtension } from '../components/extension/paragraph'
import { SubmitExtension, type SubmitOptions } from '../components/extension/submit'
@ -195,7 +195,7 @@ async function buildEditorKit (): Promise<Extension<EditorKitOptions, any>> {
staticKitExtensions.push([
500,
ListKeymap.configure({
ListKeymapExtension.configure({
listTypes: [
{
itemName: 'listItem',