import { DOMOutputSpec, MarkSpec, Mark as ProseMirrorMark, MarkType, } from 'prosemirror-model' import { Plugin } from 'prosemirror-state' import { ExtensionConfig } from './Extension' import { Attribute, Overwrite } from './types' import { Editor } from './Editor' export interface MarkConfig extends Overwrite, { /** * Inclusive */ inclusive?: MarkSpec['inclusive'] | ((this: { options: Options }) => MarkSpec['inclusive']), /** * Excludes */ excludes?: MarkSpec['excludes'] | ((this: { options: Options }) => MarkSpec['excludes']), /** * Group */ group?: MarkSpec['group'] | ((this: { options: Options }) => MarkSpec['group']), /** * Spanning */ spanning?: MarkSpec['spanning'] | ((this: { options: Options }) => MarkSpec['spanning']), /** * Parse HTML */ parseHTML?: ( this: { options: Options, }, ) => MarkSpec['parseDOM'], /** * Render HTML */ renderHTML?: (( this: { options: Options, }, props: { mark: ProseMirrorMark, HTMLAttributes: { [key: string]: any }, } ) => DOMOutputSpec) | null, /** * Attributes */ addAttributes?: ( this: { options: Options, }, ) => { [key: string]: Attribute }, /** * Commands */ addCommands?: (this: { options: Options, editor: Editor, type: MarkType, }) => Commands, /** * Keyboard shortcuts */ addKeyboardShortcuts?: (this: { options: Options, editor: Editor, type: MarkType, }) => { [key: string]: any }, /** * Input rules */ addInputRules?: (this: { options: Options, editor: Editor, type: MarkType, }) => any[], /** * Paste rules */ addPasteRules?: (this: { options: Options, editor: Editor, type: MarkType, }) => any[], /** * ProseMirror plugins */ addProseMirrorPlugins?: (this: { options: Options, editor: Editor, type: MarkType, }) => Plugin[], }> {} export class Mark { config: Required = { name: 'mark', defaultOptions: {}, addGlobalAttributes: () => [], addCommands: () => ({}), addKeyboardShortcuts: () => ({}), addInputRules: () => [], addPasteRules: () => [], addProseMirrorPlugins: () => [], inclusive: null, excludes: null, group: null, spanning: null, parseHTML: () => null, renderHTML: null, addAttributes: () => ({}), } options!: Options constructor(config: MarkConfig) { this.config = { ...this.config, ...config, } this.options = this.config.defaultOptions } static create(config: MarkConfig) { return new Mark(config) } configure(options: Partial) { return Mark .create(this.config as MarkConfig) .#configure({ ...this.config.defaultOptions, ...options, }) } #configure = (options: Partial) => { this.options = { ...this.config.defaultOptions, ...options, } return this } extend(extendedConfig: Partial>) { return new Mark({ ...this.config, ...extendedConfig, } as MarkConfig) } }