From a9fcdfc61df7070c4ba92115b9b2429e132ff9d0 Mon Sep 17 00:00:00 2001 From: Alexander Onnikov Date: Tue, 24 Sep 2024 00:22:08 +0700 Subject: [PATCH] UBERF-8240 Add editor extension for editable state change tracking (#6693) Signed-off-by: Alexander Onnikov --- .../src/components/extension/codeblock.ts | 3 +- .../src/components/extension/editable.ts | 33 +++++++++++++++++++ .../src/components/extension/focus.ts | 1 + .../src/components/extension/submit.ts | 1 + .../src/kits/editor-kit.ts | 2 ++ 5 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 plugins/text-editor-resources/src/components/extension/editable.ts diff --git a/plugins/text-editor-resources/src/components/extension/codeblock.ts b/plugins/text-editor-resources/src/components/extension/codeblock.ts index 40c2c4ebad..43d3c8dc0a 100644 --- a/plugins/text-editor-resources/src/components/extension/codeblock.ts +++ b/plugins/text-editor-resources/src/components/extension/codeblock.ts @@ -21,6 +21,7 @@ import { type Node as ProseMirrorNode } from '@tiptap/pm/model' import { Plugin, PluginKey } from '@tiptap/pm/state' import { Decoration, DecorationSet, type EditorView } from '@tiptap/pm/view' import { common, createLowlight } from 'lowlight' +import { isChangeEditable } from './editable' type Lowlight = ReturnType @@ -117,7 +118,7 @@ export function LanguageSelector (options: CodeBlockLowlightOptions): Plugin { return createDecorations(state.doc, options) }, apply (tr, prev) { - if (tr.docChanged) { + if (tr.docChanged || isChangeEditable(tr)) { return createDecorations(tr.doc, options) } diff --git a/plugins/text-editor-resources/src/components/extension/editable.ts b/plugins/text-editor-resources/src/components/extension/editable.ts new file mode 100644 index 0000000000..b2dc5eca75 --- /dev/null +++ b/plugins/text-editor-resources/src/components/extension/editable.ts @@ -0,0 +1,33 @@ +import { Extension } from '@tiptap/core' +import { type Transaction } from '@tiptap/pm/state' + +const metaKey = '$editable' + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +export interface EditableOptions {} + +export interface EditableStorage { + isEditable: boolean | undefined +} + +export function isChangeEditable (tr: Transaction): boolean { + return tr.getMeta(metaKey) !== undefined +} + +export const EditableExtension = Extension.create({ + name: 'editable', + + addStorage () { + return { isEditable: undefined } + }, + + onUpdate () { + if (this.editor.isEditable !== this.storage.isEditable) { + const { state, view } = this.editor + + this.storage.isEditable = this.editor.isEditable + const tr = state.tr.setMeta(metaKey, this.storage.isEditable) + view.dispatch(tr) + } + } +}) diff --git a/plugins/text-editor-resources/src/components/extension/focus.ts b/plugins/text-editor-resources/src/components/extension/focus.ts index 778c6033cd..af23ad14d5 100644 --- a/plugins/text-editor-resources/src/components/extension/focus.ts +++ b/plugins/text-editor-resources/src/components/extension/focus.ts @@ -22,6 +22,7 @@ export interface FocusStorage { } export const FocusExtension = Extension.create({ + name: 'focus', addStorage () { return { canBlur: true } }, diff --git a/plugins/text-editor-resources/src/components/extension/submit.ts b/plugins/text-editor-resources/src/components/extension/submit.ts index 37526fd390..bede6c2675 100644 --- a/plugins/text-editor-resources/src/components/extension/submit.ts +++ b/plugins/text-editor-resources/src/components/extension/submit.ts @@ -6,6 +6,7 @@ export interface SubmitOptions { } export const SubmitExtension = Extension.create({ + name: 'submit', addKeyboardShortcuts () { const shortcuts: Record = { Space: () => { diff --git a/plugins/text-editor-resources/src/kits/editor-kit.ts b/plugins/text-editor-resources/src/kits/editor-kit.ts index a852f7edde..3c986bd86f 100644 --- a/plugins/text-editor-resources/src/kits/editor-kit.ts +++ b/plugins/text-editor-resources/src/kits/editor-kit.ts @@ -23,6 +23,7 @@ import ListKeymap from '@tiptap/extension-list-keymap' import TableHeader from '@tiptap/extension-table-header' import 'prosemirror-codemark/dist/codemark.css' +import { EditableExtension } from '../components/extension/editable' import { CodeBlockHighlighExtension, codeBlockHighlightOptions } from '../components/extension/codeblock' import { NoteExtension, type NoteOptions } from '../components/extension/note' import { FileExtension, type FileOptions } from '../components/extension/fileExt' @@ -172,6 +173,7 @@ async function buildEditorKit (): Promise> { } }) ], + [110, EditableExtension], [200, CodeBlockHighlighExtension.configure(codeBlockHighlightOptions)], [210, CodeExtension.configure(codeOptions)], [220, HardBreakExtension.configure({ shortcuts: mode })]