diff --git a/docs/src/demos/Examples/CollaborativeEditing/index.vue b/docs/src/demos/Examples/CollaborativeEditing/index.vue index 5b5f11c0..5b17fba0 100644 --- a/docs/src/demos/Examples/CollaborativeEditing/index.vue +++ b/docs/src/demos/Examples/CollaborativeEditing/index.vue @@ -114,7 +114,6 @@ export default { return { name: this.getRandomName(), color: this.getRandomColor(), - provider: null, indexdb: null, editor: null, users: [], @@ -123,17 +122,17 @@ export default { mounted() { const ydoc = new Y.Doc() - this.provider = new WebrtcProvider('tiptap-collaboration-example', ydoc) + const provider = new WebrtcProvider('tiptap-collaboration-example', ydoc) this.indexdb = new IndexeddbPersistence('tiptap-collaboration-example', ydoc) this.editor = new Editor({ extensions: [ ...defaultExtensions(), Collaboration.configure({ - provider: this.provider, + provider, }), CollaborationCursor.configure({ - provider: this.provider, + provider, user: { name: this.name, color: this.color, @@ -201,7 +200,6 @@ export default { beforeDestroy() { this.editor.destroy() - this.provider.destroy() }, } diff --git a/packages/core/src/Editor.ts b/packages/core/src/Editor.ts index b6904d11..8731902a 100644 --- a/packages/core/src/Editor.ts +++ b/packages/core/src/Editor.ts @@ -385,6 +385,8 @@ export class Editor extends EventEmitter { * Destroy the editor. */ public destroy() { + this.emit('destroy') + if (this.view) { this.view.destroy() } diff --git a/packages/core/src/Extension.ts b/packages/core/src/Extension.ts index 48a4a3cf..4f62537d 100644 --- a/packages/core/src/Extension.ts +++ b/packages/core/src/Extension.ts @@ -62,6 +62,11 @@ export interface ExtensionConfig { options: Options, editor: Editor, }) => Plugin[], + + onDestroy?: ((this: { + options: Options, + editor: Editor, + }) => void) | null, } export class Extension { @@ -76,6 +81,7 @@ export class Extension { addInputRules: () => [], addPasteRules: () => [], addProseMirrorPlugins: () => [], + onDestroy: null, } options!: Options diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index ecd6dce5..1063a002 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -33,6 +33,10 @@ export default class ExtensionManager { const commands = extension.config.addCommands.bind(context)() editor.registerCommands(commands) + + if (typeof extension.config.onDestroy === 'function') { + this.editor.on('destroy', extension.config.onDestroy.bind(context)) + } }) } diff --git a/packages/core/src/Mark.ts b/packages/core/src/Mark.ts index 07bc21eb..a76a6398 100644 --- a/packages/core/src/Mark.ts +++ b/packages/core/src/Mark.ts @@ -108,6 +108,12 @@ export interface MarkConfig extends Overwrite Plugin[], + + onDestroy?: ((this: { + options: Options, + editor: Editor, + type: MarkType, + }) => void) | null, }> {} export class Mark { @@ -129,6 +135,7 @@ export class Mark { parseHTML: () => null, renderHTML: null, addAttributes: () => ({}), + onDestroy: null, } options!: Options diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts index 8dd1308d..f1379d19 100644 --- a/packages/core/src/Node.ts +++ b/packages/core/src/Node.ts @@ -152,6 +152,12 @@ export interface NodeConfig extends Overwrite NodeViewRenderer) | null, + + onDestroy?: ((this: { + options: Options, + editor: Editor, + type: NodeType, + }) => void) | null, }> {} export class Node { @@ -181,6 +187,7 @@ export class Node { renderHTML: null, addAttributes: () => ({}), addNodeView: null, + onDestroy: null, } options!: Options diff --git a/packages/extension-collaboration/src/index.ts b/packages/extension-collaboration/src/index.ts index 0bf64d4c..976d1adb 100644 --- a/packages/extension-collaboration/src/index.ts +++ b/packages/extension-collaboration/src/index.ts @@ -31,6 +31,10 @@ const Collaboration = Extension.create({ 'Mod-Shift-z': redo, } }, + + onDestroy() { + this.options.provider?.destroy() + }, }) export default Collaboration