mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-08 01:53:04 +08:00
feature(core): add onPaste and onDrop events to editor (#4843)
This commit is contained in:
parent
da8fcf373e
commit
9e18d243e0
5
.changeset/lovely-bears-wonder.md
Normal file
5
.changeset/lovely-bears-wonder.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@tiptap/core": minor
|
||||||
|
---
|
||||||
|
|
||||||
|
Added `onPaste` and `onDrop` options to the editor allowing for easier event binding for both cases
|
5
.changeset/nine-pianos-move.md
Normal file
5
.changeset/nine-pianos-move.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@tiptap/vue-3": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fixed an issue where plugin registration on editor initialization would break Vue3 editors.
|
@ -24,6 +24,8 @@ import { isActive } from './helpers/isActive.js'
|
|||||||
import { isNodeEmpty } from './helpers/isNodeEmpty.js'
|
import { isNodeEmpty } from './helpers/isNodeEmpty.js'
|
||||||
import { resolveFocusPosition } from './helpers/resolveFocusPosition.js'
|
import { resolveFocusPosition } from './helpers/resolveFocusPosition.js'
|
||||||
import { NodePos } from './NodePos.js'
|
import { NodePos } from './NodePos.js'
|
||||||
|
import { DropPlugin } from './plugins/DropPlugin.js'
|
||||||
|
import { PastePlugin } from './plugins/PastePlugin.js'
|
||||||
import { style } from './style.js'
|
import { style } from './style.js'
|
||||||
import {
|
import {
|
||||||
CanCommands,
|
CanCommands,
|
||||||
@ -88,6 +90,8 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|||||||
onBlur: () => null,
|
onBlur: () => null,
|
||||||
onDestroy: () => null,
|
onDestroy: () => null,
|
||||||
onContentError: ({ error }) => { throw error },
|
onContentError: ({ error }) => { throw error },
|
||||||
|
onPaste: () => null,
|
||||||
|
onDrop: () => null,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(options: Partial<EditorOptions> = {}) {
|
constructor(options: Partial<EditorOptions> = {}) {
|
||||||
@ -109,6 +113,14 @@ export class Editor extends EventEmitter<EditorEvents> {
|
|||||||
this.on('blur', this.options.onBlur)
|
this.on('blur', this.options.onBlur)
|
||||||
this.on('destroy', this.options.onDestroy)
|
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(() => {
|
window.setTimeout(() => {
|
||||||
if (this.isDestroyed) {
|
if (this.isDestroyed) {
|
||||||
return
|
return
|
||||||
|
@ -11,6 +11,8 @@ export * from './NodePos.js'
|
|||||||
export * from './NodeView.js'
|
export * from './NodeView.js'
|
||||||
export * from './PasteRule.js'
|
export * from './PasteRule.js'
|
||||||
export * from './pasteRules/index.js'
|
export * from './pasteRules/index.js'
|
||||||
|
export * from './plugins/DropPlugin.js'
|
||||||
|
export * from './plugins/PastePlugin.js'
|
||||||
export * from './Tracker.js'
|
export * from './Tracker.js'
|
||||||
export * from './types.js'
|
export * from './types.js'
|
||||||
export * from './utilities/index.js'
|
export * from './utilities/index.js'
|
||||||
|
14
packages/core/src/plugins/DropPlugin.ts
Normal file
14
packages/core/src/plugins/DropPlugin.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { Plugin, PluginKey } from '@tiptap/pm/state'
|
||||||
|
import { Slice } from 'packages/pm/model'
|
||||||
|
|
||||||
|
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)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
14
packages/core/src/plugins/PastePlugin.ts
Normal file
14
packages/core/src/plugins/PastePlugin.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
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)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@ -3,6 +3,7 @@ import {
|
|||||||
Node as ProseMirrorNode,
|
Node as ProseMirrorNode,
|
||||||
NodeType,
|
NodeType,
|
||||||
ParseOptions,
|
ParseOptions,
|
||||||
|
Slice,
|
||||||
} from '@tiptap/pm/model'
|
} from '@tiptap/pm/model'
|
||||||
import { EditorState, Transaction } from '@tiptap/pm/state'
|
import { EditorState, Transaction } from '@tiptap/pm/state'
|
||||||
import {
|
import {
|
||||||
@ -121,6 +122,8 @@ export interface EditorOptions {
|
|||||||
onFocus: (props: EditorEvents['focus']) => void;
|
onFocus: (props: EditorEvents['focus']) => void;
|
||||||
onBlur: (props: EditorEvents['blur']) => void;
|
onBlur: (props: EditorEvents['blur']) => void;
|
||||||
onDestroy: (props: EditorEvents['destroy']) => void;
|
onDestroy: (props: EditorEvents['destroy']) => void;
|
||||||
|
onPaste: (e: ClipboardEvent, slice: Slice) => void
|
||||||
|
onDrop: (e: DragEvent, slice: Slice, moved: boolean) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type HTMLContent = string;
|
export type HTMLContent = string;
|
||||||
|
@ -149,6 +149,8 @@ class EditorInstanceManager {
|
|||||||
onTransaction: (...args) => this.options.current.onTransaction?.(...args),
|
onTransaction: (...args) => this.options.current.onTransaction?.(...args),
|
||||||
onUpdate: (...args) => this.options.current.onUpdate?.(...args),
|
onUpdate: (...args) => this.options.current.onUpdate?.(...args),
|
||||||
onContentError: (...args) => this.options.current.onContentError?.(...args),
|
onContentError: (...args) => this.options.current.onContentError?.(...args),
|
||||||
|
onDrop: (...args) => this.options.current.onDrop?.(...args),
|
||||||
|
onPaste: (...args) => this.options.current.onPaste?.(...args),
|
||||||
}
|
}
|
||||||
const editor = new Editor(optionsToApply)
|
const editor = new Editor(optionsToApply)
|
||||||
|
|
||||||
|
@ -75,14 +75,18 @@ export class Editor extends CoreEditor {
|
|||||||
handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],
|
handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[],
|
||||||
): void {
|
): void {
|
||||||
super.registerPlugin(plugin, handlePlugins)
|
super.registerPlugin(plugin, handlePlugins)
|
||||||
|
if (this.reactiveState) {
|
||||||
this.reactiveState.value = this.view.state
|
this.reactiveState.value = this.view.state
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregister a ProseMirror plugin.
|
* Unregister a ProseMirror plugin.
|
||||||
*/
|
*/
|
||||||
public unregisterPlugin(nameOrPluginKey: string | PluginKey): void {
|
public unregisterPlugin(nameOrPluginKey: string | PluginKey): void {
|
||||||
super.unregisterPlugin(nameOrPluginKey)
|
super.unregisterPlugin(nameOrPluginKey)
|
||||||
|
if (this.reactiveState) {
|
||||||
this.reactiveState.value = this.view.state
|
this.reactiveState.value = this.view.state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user