From f6689edd0b1216bafccd6f50d178f78cde91561d Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Mon, 30 Sep 2024 11:37:01 +0200 Subject: [PATCH 1/4] fix(core): onDrop and onPaste only registered when defined #5681 --- packages/core/src/Editor.ts | 22 +++++++------- packages/core/src/extensions/drop.ts | 38 ++++++++++++++++++++++++ packages/core/src/extensions/index.ts | 2 ++ packages/core/src/extensions/paste.ts | 38 ++++++++++++++++++++++++ packages/core/src/plugins/DropPlugin.ts | 14 --------- packages/core/src/plugins/PastePlugin.ts | 14 --------- 6 files changed, 89 insertions(+), 39 deletions(-) create mode 100644 packages/core/src/extensions/drop.ts create mode 100644 packages/core/src/extensions/paste.ts delete mode 100644 packages/core/src/plugins/DropPlugin.ts delete mode 100644 packages/core/src/plugins/PastePlugin.ts diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index c8ecff2233d..a3428e0efc7 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -13,7 +13,8 @@ import { CommandManager } from './CommandManager.js' import { EventEmitter } from './EventEmitter.js' import { ExtensionManager } from './ExtensionManager.js' import { - ClipboardTextSerializer, Commands, Editable, FocusEvents, Keymap, Tabindex, + ClipboardTextSerializer, Commands, Drop, Editable, FocusEvents, Keymap, Paste, + Tabindex, } from './extensions/index.js' import { createDocument } from './helpers/createDocument.js' import { getAttributes } from './helpers/getAttributes.js' @@ -24,8 +25,6 @@ import { isActive } from './helpers/isActive.js' import { isNodeEmpty } from './helpers/isNodeEmpty.js' import { resolveFocusPosition } from './helpers/resolveFocusPosition.js' import { NodePos } from './NodePos.js' -import { DropPlugin } from './plugins/DropPlugin.js' -import { PastePlugin } from './plugins/PastePlugin.js' import { style } from './style.js' import { CanCommands, @@ -113,14 +112,6 @@ export class Editor extends EventEmitter { this.on('blur', this.options.onBlur) this.on('destroy', this.options.onDestroy) - if (this.options.onPaste) { - this.registerPlugin(PastePlugin(this.options.onPaste)) - } - - if (this.options.onDrop) { - this.registerPlugin(DropPlugin(this.options.onDrop)) - } - window.setTimeout(() => { if (this.isDestroyed) { return @@ -279,7 +270,16 @@ export class Editor extends EventEmitter { FocusEvents, Keymap, Tabindex, + this.options.onDrop && Drop.configure({ + onDrop: this.options.onDrop, + }), + this.options.onPaste && Paste.configure({ + onPaste: this.options.onPaste, + }), ].filter(ext => { + if (!ext) { + return false + } if (typeof this.options.enableCoreExtensions === 'object') { return this.options.enableCoreExtensions[ext.name as keyof typeof this.options.enableCoreExtensions] !== false } diff --git a/packages/core/src/extensions/drop.ts b/packages/core/src/extensions/drop.ts new file mode 100644 index 00000000000..4dbee367235 --- /dev/null +++ b/packages/core/src/extensions/drop.ts @@ -0,0 +1,38 @@ +import type { Slice } from '@tiptap/pm/model' +import { Plugin, PluginKey } from '@tiptap/pm/state' + +import { Extension } from '../Extension.js' + +export type DropOptions = { + onDrop?: (e: DragEvent, slice: Slice, moved: boolean) => void; +} + +export const Drop = Extension.create({ + name: 'drop', + + addOptions() { + return { + onDrop: undefined, + } + }, + + addProseMirrorPlugins() { + const onDrop = this.options.onDrop + + if (!onDrop) { + return [] + } + + return [ + new Plugin({ + key: new PluginKey('tiptapDrop'), + + props: { + handleDrop: (_, e, slice, moved) => { + onDrop(e, slice, moved) + }, + }, + }), + ] + }, +}) diff --git a/packages/core/src/extensions/index.ts b/packages/core/src/extensions/index.ts index 139cdd891b6..eca0516c7ed 100644 --- a/packages/core/src/extensions/index.ts +++ b/packages/core/src/extensions/index.ts @@ -1,6 +1,8 @@ export { ClipboardTextSerializer } from './clipboardTextSerializer.js' export { Commands } from './commands.js' +export { Drop } from './drop.js' export { Editable } from './editable.js' export { FocusEvents } from './focusEvents.js' export { Keymap } from './keymap.js' +export { Paste } from './paste.js' export { Tabindex } from './tabindex.js' diff --git a/packages/core/src/extensions/paste.ts b/packages/core/src/extensions/paste.ts new file mode 100644 index 00000000000..9beaa8e77d8 --- /dev/null +++ b/packages/core/src/extensions/paste.ts @@ -0,0 +1,38 @@ +import type { Slice } from '@tiptap/pm/model' +import { Plugin, PluginKey } from '@tiptap/pm/state' + +import { Extension } from '../Extension.js' + +export type PastOptions = { + onPaste?: (e: ClipboardEvent, slice: Slice) => void; +} + +export const Paste = Extension.create({ + name: 'paste', + + addOptions() { + return { + onPaste: undefined, + } + }, + + addProseMirrorPlugins() { + const onPaste = this.options.onPaste + + if (!onPaste) { + return [] + } + + return [ + new Plugin({ + key: new PluginKey('tiptapPaste'), + + props: { + handlePaste: (_view, e, slice) => { + onPaste(e, slice) + }, + }, + }), + ] + }, +}) diff --git a/packages/core/src/plugins/DropPlugin.ts b/packages/core/src/plugins/DropPlugin.ts deleted file mode 100644 index 48e52d88b94..00000000000 --- a/packages/core/src/plugins/DropPlugin.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Slice } from '@tiptap/pm/model' -import { Plugin, PluginKey } from '@tiptap/pm/state' - -export const DropPlugin = (onDrop: (e: DragEvent, slice: Slice, moved: boolean) => void) => { - return new Plugin({ - key: new PluginKey('tiptapDrop'), - - props: { - handleDrop: (_, e, slice, moved) => { - onDrop(e, slice, moved) - }, - }, - }) -} diff --git a/packages/core/src/plugins/PastePlugin.ts b/packages/core/src/plugins/PastePlugin.ts deleted file mode 100644 index afe5d9c9b1b..00000000000 --- a/packages/core/src/plugins/PastePlugin.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Slice } from '@tiptap/pm/model' -import { Plugin, PluginKey } from '@tiptap/pm/state' - -export const PastePlugin = (onPaste: (e: ClipboardEvent, slice: Slice) => void) => { - return new Plugin({ - key: new PluginKey('tiptapPaste'), - - props: { - handlePaste: (_view, e, slice) => { - onPaste(e, slice) - }, - }, - }) -} From 33fb17a9019e041454052edd84a88c64c7cb208e Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Mon, 30 Sep 2024 11:56:06 +0200 Subject: [PATCH 2/4] refactor: move to be an actual event --- packages/core/src/Editor.ts | 13 ++++--------- packages/core/src/extensions/drop.ts | 23 ++++------------------- packages/core/src/extensions/paste.ts | 24 ++++++------------------ packages/core/src/types.ts | 6 +++++- 4 files changed, 19 insertions(+), 47 deletions(-) diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index a3428e0efc7..b7a58cd0d1c 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -111,6 +111,8 @@ export class Editor extends EventEmitter { this.on('focus', this.options.onFocus) this.on('blur', this.options.onBlur) this.on('destroy', this.options.onDestroy) + this.on('drop', ({ event, slice, moved }) => this.options.onDrop(event, slice, moved)) + this.on('paste', ({ event, slice }) => this.options.onPaste(event, slice)) window.setTimeout(() => { if (this.isDestroyed) { @@ -270,16 +272,9 @@ export class Editor extends EventEmitter { FocusEvents, Keymap, Tabindex, - this.options.onDrop && Drop.configure({ - onDrop: this.options.onDrop, - }), - this.options.onPaste && Paste.configure({ - onPaste: this.options.onPaste, - }), + Drop, + Paste, ].filter(ext => { - if (!ext) { - return false - } if (typeof this.options.enableCoreExtensions === 'object') { return this.options.enableCoreExtensions[ext.name as keyof typeof this.options.enableCoreExtensions] !== false } diff --git a/packages/core/src/extensions/drop.ts b/packages/core/src/extensions/drop.ts index 4dbee367235..d229abce1ce 100644 --- a/packages/core/src/extensions/drop.ts +++ b/packages/core/src/extensions/drop.ts @@ -1,35 +1,20 @@ -import type { Slice } from '@tiptap/pm/model' import { Plugin, PluginKey } from '@tiptap/pm/state' import { Extension } from '../Extension.js' -export type DropOptions = { - onDrop?: (e: DragEvent, slice: Slice, moved: boolean) => void; -} - -export const Drop = Extension.create({ +export const Drop = Extension.create({ name: 'drop', - addOptions() { - return { - onDrop: undefined, - } - }, - addProseMirrorPlugins() { - const onDrop = this.options.onDrop - - if (!onDrop) { - return [] - } - return [ new Plugin({ key: new PluginKey('tiptapDrop'), props: { handleDrop: (_, e, slice, moved) => { - onDrop(e, slice, moved) + this.editor.emit('drop', { + editor: this.editor, event: e, slice, moved, + }) }, }, }), diff --git a/packages/core/src/extensions/paste.ts b/packages/core/src/extensions/paste.ts index 9beaa8e77d8..56ea385b7c3 100644 --- a/packages/core/src/extensions/paste.ts +++ b/packages/core/src/extensions/paste.ts @@ -1,27 +1,11 @@ -import type { Slice } from '@tiptap/pm/model' import { Plugin, PluginKey } from '@tiptap/pm/state' import { Extension } from '../Extension.js' -export type PastOptions = { - onPaste?: (e: ClipboardEvent, slice: Slice) => void; -} - -export const Paste = Extension.create({ +export const Paste = Extension.create({ name: 'paste', - addOptions() { - return { - onPaste: undefined, - } - }, - addProseMirrorPlugins() { - const onPaste = this.options.onPaste - - if (!onPaste) { - return [] - } return [ new Plugin({ @@ -29,7 +13,11 @@ export const Paste = Extension.create({ props: { handlePaste: (_view, e, slice) => { - onPaste(e, slice) + this.editor.emit('paste', { + editor: this.editor, + event: e, + slice, + }) }, }, }), diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index acafa61817a..8a29500c186 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -63,6 +63,8 @@ export interface EditorEvents { focus: { editor: Editor; event: FocusEvent; transaction: Transaction }; blur: { editor: Editor; event: FocusEvent; transaction: Transaction }; destroy: void; + paste: { editor: Editor; event: ClipboardEvent; slice: Slice }; + drop: { editor: Editor; event: DragEvent; slice: Slice; moved: boolean }; } export type EnableRules = (AnyExtension | string)[] | boolean; @@ -110,7 +112,9 @@ export interface EditorOptions { | 'commands' | 'focusEvents' | 'keymap' - | 'tabindex', + | 'tabindex' + | 'drop' + | 'paste', false > >; From 1c34bbdf9fd4e63600eab7a27273f0478d7c33fb Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Mon, 30 Sep 2024 12:00:53 +0200 Subject: [PATCH 3/4] fix: rm export --- packages/core/src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index a464930dc20..ccfa709259c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -11,8 +11,6 @@ export * from './NodePos.js' export * from './NodeView.js' export * from './PasteRule.js' export * from './pasteRules/index.js' -export * from './plugins/DropPlugin.js' -export * from './plugins/PastePlugin.js' export * from './Tracker.js' export * from './types.js' export * from './utilities/index.js' From dcacb0ea10616f6239fcee94a6a721e92da25a72 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Mon, 30 Sep 2024 12:19:41 +0200 Subject: [PATCH 4/4] refactor: style --- packages/core/src/extensions/drop.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/core/src/extensions/drop.ts b/packages/core/src/extensions/drop.ts index d229abce1ce..0d079a0f019 100644 --- a/packages/core/src/extensions/drop.ts +++ b/packages/core/src/extensions/drop.ts @@ -13,7 +13,10 @@ export const Drop = Extension.create({ props: { handleDrop: (_, e, slice, moved) => { this.editor.emit('drop', { - editor: this.editor, event: e, slice, moved, + editor: this.editor, + event: e, + slice, + moved, }) }, },