Merge branch 'main' of github.com:ueberdosis/tiptap-next into main

This commit is contained in:
Hans Pagel
2020-11-30 14:14:06 +01:00
7 changed files with 271 additions and 9 deletions

View File

@@ -10,7 +10,7 @@ You can define your event listeners on a new editor instance right-away:
```js ```js
const editor = new Editor({ const editor = new Editor({
onInit() { onCreate() {
// The editor is ready. // The editor is ready.
}, },
onUpdate() { onUpdate() {
@@ -28,6 +28,9 @@ const editor = new Editor({
onBlur({ event }) { onBlur({ event }) {
// The editor isnt focused anymore. // The editor isnt focused anymore.
}, },
onDestroy() {
// The editor is destroyed.
},
}) })
``` ```
@@ -36,7 +39,7 @@ Or you can register your event listeners on a running editor instance:
### Bind event listeners ### Bind event listeners
```js ```js
editor.on('init', () => { editor.on('create', () => {
// The editor is ready. // The editor is ready.
} }
@@ -59,6 +62,10 @@ editor.on('focus', ({ event }) => {
editor.on('blur', ({ event }) => { editor.on('blur', ({ event }) => {
// The editor isnt focused anymore. // The editor isnt focused anymore.
} }
editor.on('destroy', () => {
// The editor is destroyed.
}
``` ```
### Unbind event listeners ### Unbind event listeners

View File

@@ -50,12 +50,13 @@ export class Editor extends EventEmitter {
parseOptions: {}, parseOptions: {},
enableInputRules: true, enableInputRules: true,
enablePasteRules: true, enablePasteRules: true,
onInit: () => null, onCreate: () => null,
onUpdate: () => null, onUpdate: () => null,
onSelection: () => null, onSelection: () => null,
onTransaction: () => null, onTransaction: () => null,
onFocus: () => null, onFocus: () => null,
onBlur: () => null, onBlur: () => null,
onDestroy: () => null,
} }
constructor(options: Partial<EditorOptions> = {}) { constructor(options: Partial<EditorOptions> = {}) {
@@ -73,16 +74,17 @@ export class Editor extends EventEmitter {
this.createSchema() this.createSchema()
this.createView() this.createView()
this.injectCSS() this.injectCSS()
this.on('init', this.options.onInit) this.on('create', this.options.onCreate)
this.on('update', this.options.onUpdate) this.on('update', this.options.onUpdate)
this.on('selection', this.options.onSelection) this.on('selection', this.options.onSelection)
this.on('transaction', this.options.onTransaction) this.on('transaction', this.options.onTransaction)
this.on('focus', this.options.onFocus) this.on('focus', this.options.onFocus)
this.on('blur', this.options.onBlur) this.on('blur', this.options.onBlur)
this.on('destroy', this.options.onDestroy)
window.setTimeout(() => { window.setTimeout(() => {
this.commands.focus(this.options.autofocus) this.commands.focus(this.options.autofocus)
this.emit('init') this.emit('create')
}, 0) }, 0)
} }

View File

@@ -1,4 +1,4 @@
import { Plugin } from 'prosemirror-state' import { Plugin, Transaction } from 'prosemirror-state'
import { InputRule } from 'prosemirror-inputrules' import { InputRule } from 'prosemirror-inputrules'
import { Editor } from './Editor' import { Editor } from './Editor'
import { GlobalAttributes } from './types' import { GlobalAttributes } from './types'
@@ -63,6 +63,72 @@ export interface ExtensionConfig<Options = any, Commands = {}> {
editor: Editor, editor: Editor,
}) => Plugin[], }) => Plugin[],
/**
* The editor is ready.
*/
onCreate?: ((this: {
options: Options,
editor: Editor,
}) => void) | null,
/**
* The content has changed.
*/
onUpdate?: ((this: {
options: Options,
editor: Editor,
}) => void) | null,
/**
* The selection has changed.
*/
onSelection?: ((this: {
options: Options,
editor: Editor,
}) => void) | null,
/**
* The editor state has changed.
*/
onTransaction?: ((
this: {
options: Options,
editor: Editor,
},
props: {
transaction: Transaction,
},
) => void) | null,
/**
* The editor is focused.
*/
onFocus?: ((
this: {
options: Options,
editor: Editor,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor isnt focused anymore.
*/
onBlur?: ((
this: {
options: Options,
editor: Editor,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor is destroyed.
*/
onDestroy?: ((this: { onDestroy?: ((this: {
options: Options, options: Options,
editor: Editor, editor: Editor,
@@ -81,6 +147,12 @@ export class Extension<Options = any, Commands = any> {
addInputRules: () => [], addInputRules: () => [],
addPasteRules: () => [], addPasteRules: () => [],
addProseMirrorPlugins: () => [], addProseMirrorPlugins: () => [],
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null, onDestroy: null,
} }

View File

@@ -34,6 +34,30 @@ export default class ExtensionManager {
editor.registerCommands(commands) editor.registerCommands(commands)
if (typeof extension.config.onCreate === 'function') {
this.editor.on('create', extension.config.onCreate.bind(context))
}
if (typeof extension.config.onUpdate === 'function') {
this.editor.on('update', extension.config.onUpdate.bind(context))
}
if (typeof extension.config.onSelection === 'function') {
this.editor.on('selection', extension.config.onSelection.bind(context))
}
if (typeof extension.config.onTransaction === 'function') {
this.editor.on('transaction', extension.config.onTransaction.bind(context))
}
if (typeof extension.config.onFocus === 'function') {
this.editor.on('focus', extension.config.onFocus.bind(context))
}
if (typeof extension.config.onBlur === 'function') {
this.editor.on('blur', extension.config.onBlur.bind(context))
}
if (typeof extension.config.onDestroy === 'function') { if (typeof extension.config.onDestroy === 'function') {
this.editor.on('destroy', extension.config.onDestroy.bind(context)) this.editor.on('destroy', extension.config.onDestroy.bind(context))
} }

View File

@@ -4,7 +4,7 @@ import {
Mark as ProseMirrorMark, Mark as ProseMirrorMark,
MarkType, MarkType,
} from 'prosemirror-model' } from 'prosemirror-model'
import { Plugin } from 'prosemirror-state' import { Plugin, Transaction } from 'prosemirror-state'
import { InputRule } from 'prosemirror-inputrules' import { InputRule } from 'prosemirror-inputrules'
import { ExtensionConfig } from './Extension' import { ExtensionConfig } from './Extension'
import { Attributes, Overwrite } from './types' import { Attributes, Overwrite } from './types'
@@ -109,6 +109,78 @@ export interface MarkConfig<Options = any, Commands = {}> extends Overwrite<Exte
type: MarkType, type: MarkType,
}) => Plugin[], }) => Plugin[],
/**
* The editor is ready.
*/
onCreate?: ((this: {
options: Options,
editor: Editor,
type: MarkType,
}) => void) | null,
/**
* The content has changed.
*/
onUpdate?: ((this: {
options: Options,
editor: Editor,
type: MarkType,
}) => void) | null,
/**
* The selection has changed.
*/
onSelection?: ((this: {
options: Options,
editor: Editor,
type: MarkType,
}) => void) | null,
/**
* The editor state has changed.
*/
onTransaction?: ((
this: {
options: Options,
editor: Editor,
type: MarkType,
},
props: {
transaction: Transaction,
},
) => void) | null,
/**
* The editor is focused.
*/
onFocus?: ((
this: {
options: Options,
editor: Editor,
type: MarkType,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor isnt focused anymore.
*/
onBlur?: ((
this: {
options: Options,
editor: Editor,
type: MarkType,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor is destroyed.
*/
onDestroy?: ((this: { onDestroy?: ((this: {
options: Options, options: Options,
editor: Editor, editor: Editor,
@@ -135,6 +207,12 @@ export class Mark<Options = any, Commands = {}> {
parseHTML: () => null, parseHTML: () => null,
renderHTML: null, renderHTML: null,
addAttributes: () => ({}), addAttributes: () => ({}),
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null, onDestroy: null,
} }

View File

@@ -4,7 +4,7 @@ import {
Node as ProseMirrorNode, Node as ProseMirrorNode,
NodeType, NodeType,
} from 'prosemirror-model' } from 'prosemirror-model'
import { Plugin } from 'prosemirror-state' import { Plugin, Transaction } from 'prosemirror-state'
import { InputRule } from 'prosemirror-inputrules' import { InputRule } from 'prosemirror-inputrules'
import { ExtensionConfig } from './Extension' import { ExtensionConfig } from './Extension'
import { Attributes, NodeViewRenderer, Overwrite } from './types' import { Attributes, NodeViewRenderer, Overwrite } from './types'
@@ -153,6 +153,78 @@ export interface NodeConfig<Options = any, Commands = {}> extends Overwrite<Exte
type: NodeType, type: NodeType,
}) => NodeViewRenderer) | null, }) => NodeViewRenderer) | null,
/**
* The editor is ready.
*/
onCreate?: ((this: {
options: Options,
editor: Editor,
type: NodeType,
}) => void) | null,
/**
* The content has changed.
*/
onUpdate?: ((this: {
options: Options,
editor: Editor,
type: NodeType,
}) => void) | null,
/**
* The selection has changed.
*/
onSelection?: ((this: {
options: Options,
editor: Editor,
type: NodeType,
}) => void) | null,
/**
* The editor state has changed.
*/
onTransaction?: ((
this: {
options: Options,
editor: Editor,
type: NodeType,
},
props: {
transaction: Transaction,
},
) => void) | null,
/**
* The editor is focused.
*/
onFocus?: ((
this: {
options: Options,
editor: Editor,
type: NodeType,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor isnt focused anymore.
*/
onBlur?: ((
this: {
options: Options,
editor: Editor,
type: NodeType,
},
props: {
event: FocusEvent,
},
) => void) | null,
/**
* The editor is destroyed.
*/
onDestroy?: ((this: { onDestroy?: ((this: {
options: Options, options: Options,
editor: Editor, editor: Editor,
@@ -187,6 +259,12 @@ export class Node<Options = any, Commands = {}> {
renderHTML: null, renderHTML: null,
addAttributes: () => ({}), addAttributes: () => ({}),
addNodeView: null, addNodeView: null,
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null, onDestroy: null,
} }

View File

@@ -25,12 +25,13 @@ export interface EditorOptions {
parseOptions: ParseOptions, parseOptions: ParseOptions,
enableInputRules: boolean, enableInputRules: boolean,
enablePasteRules: boolean, enablePasteRules: boolean,
onInit: () => void, onCreate: () => void,
onUpdate: () => void, onUpdate: () => void,
onSelection: () => void, onSelection: () => void,
onTransaction: (props: { transaction: Transaction }) => void, onTransaction: (props: { transaction: Transaction }) => void,
onFocus: (props: { event: FocusEvent }) => void, onFocus: (props: { event: FocusEvent }) => void,
onBlur: (props: { event: FocusEvent }) => void, onBlur: (props: { event: FocusEvent }) => void,
onDestroy: () => void,
} }
export type EditorContent = string | JSON | null export type EditorContent = string | JSON | null