improve extending nodes and marks

This commit is contained in:
Philipp Kühn
2021-02-19 10:54:47 +01:00
parent 4a58978ffb
commit ba69a0d8f9
8 changed files with 60 additions and 106 deletions

View File

@@ -165,24 +165,9 @@ export interface ExtensionConfig<Options = any> {
export class Extension<Options = any> {
type = 'extension'
config: Required<ExtensionConfig> = {
config: ExtensionConfig = {
name: 'extension',
defaultOptions: {},
addGlobalAttributes: () => [],
addCommands: () => ({}),
addKeyboardShortcuts: () => ({}),
addInputRules: () => [],
addPasteRules: () => [],
addProseMirrorPlugins: () => [],
extendNodeSchema: null,
extendMarkSchema: null,
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null,
}
options!: Options

View File

@@ -70,6 +70,10 @@ export default class ExtensionManager {
type: getSchemaTypeByName(extension.config.name, this.schema),
}
if (!extension.config.addCommands) {
return commands
}
return {
...commands,
...extension.config.addCommands.bind(context)(),
@@ -87,22 +91,36 @@ export default class ExtensionManager {
type: getSchemaTypeByName(extension.config.name, this.schema),
}
const keymapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)())
const inputRules = extension.config.addInputRules.bind(context)()
const inputRulePlugins = this.editor.options.enableInputRules && inputRules.length
? [inputRulesPlugin({ rules: inputRules })]
: []
const pasteRulePlugins = this.editor.options.enablePasteRules
? extension.config.addPasteRules.bind(context)()
: []
const plugins = extension.config.addProseMirrorPlugins.bind(context)()
const plugins: Plugin[] = []
return [
keymapPlugin,
...inputRulePlugins,
...pasteRulePlugins,
...plugins,
]
if (extension.config.addKeyboardShortcuts) {
const keyMapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)())
plugins.push(keyMapPlugin)
}
if (this.editor.options.enableInputRules && extension.config.addInputRules) {
const inputRules = extension.config.addInputRules.bind(context)()
const inputRulePlugins = inputRules.length
? [inputRulesPlugin({ rules: inputRules })]
: []
plugins.push(...inputRulePlugins)
}
if (this.editor.options.enablePasteRules && extension.config.addPasteRules) {
const pasteRulePlugins = extension.config.addPasteRules.bind(context)()
plugins.push(...pasteRulePlugins)
}
if (extension.config.addProseMirrorPlugins) {
const proseMirrorPlugins = extension.config.addProseMirrorPlugins.bind(context)()
proseMirrorPlugins.push(...proseMirrorPlugins)
}
return plugins
})
.flat()
}

View File

@@ -193,31 +193,9 @@ export interface MarkConfig<Options = any> extends Overwrite<ExtensionConfig<Opt
export class Mark<Options = any> {
type = 'mark'
config: Required<MarkConfig> = {
config: MarkConfig = {
name: 'mark',
defaultOptions: {},
addGlobalAttributes: () => [],
addCommands: () => ({}),
addKeyboardShortcuts: () => ({}),
addInputRules: () => [],
addPasteRules: () => [],
addProseMirrorPlugins: () => [],
inclusive: null,
excludes: null,
group: null,
spanning: null,
parseHTML: () => null,
renderHTML: null,
addAttributes: () => ({}),
extendNodeSchema: null,
extendMarkSchema: null,
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null,
}
options!: Options

View File

@@ -14,7 +14,6 @@ import {
NodeViewRenderer,
Overwrite,
RawCommands,
NodeSchemaFields,
} from './types'
import { Editor } from './Editor'
@@ -257,45 +256,14 @@ export interface NodeConfig<Options = any> extends Overwrite<ExtensionConfig<Opt
export class Node<Options = any> {
type = 'node'
config: Required<NodeConfig> & NodeSchemaFields<Options> = {
config: NodeConfig = {
name: 'node',
defaultOptions: {},
addGlobalAttributes: () => [],
addCommands: () => ({}),
addKeyboardShortcuts: () => ({}),
addInputRules: () => [],
addPasteRules: () => [],
addProseMirrorPlugins: () => [],
topNode: false,
content: null,
marks: null,
group: null,
inline: null,
atom: null,
selectable: null,
draggable: null,
code: null,
defining: null,
isolating: null,
parseHTML: () => null,
renderHTML: null,
renderText: null,
addAttributes: () => ({}),
addNodeView: null,
extendNodeSchema: null,
extendMarkSchema: null,
onCreate: null,
onUpdate: null,
onSelection: null,
onTransaction: null,
onFocus: null,
onBlur: null,
onDestroy: null,
}
options!: Options
constructor(config: NodeConfig<Options> & NodeSchemaFields<Options>) {
constructor(config: NodeConfig<Options>) {
this.config = {
...this.config,
...config,
@@ -304,13 +272,13 @@ export class Node<Options = any> {
this.options = this.config.defaultOptions
}
static create<O>(config: NodeConfig<O> & NodeSchemaFields<O>) {
static create<O>(config: NodeConfig<O>) {
return new Node<O>(config)
}
configure(options: Partial<Options> = {}) {
return Node
.create<Options>(this.config as (NodeConfig<Options> & NodeSchemaFields<Options>))
.create<Options>(this.config as NodeConfig<Options>)
.#configure(options)
}
@@ -320,10 +288,10 @@ export class Node<Options = any> {
return this
}
extend<ExtendedOptions = Options>(extendedConfig: Partial<NodeConfig<ExtendedOptions> & NodeSchemaFields<ExtendedOptions>>) {
extend<ExtendedOptions = Options>(extendedConfig: Partial<NodeConfig<ExtendedOptions>>) {
return new Node<ExtendedOptions>({
...this.config,
...extendedConfig,
} as NodeConfig<ExtendedOptions> & NodeSchemaFields<ExtendedOptions>)
} as NodeConfig<ExtendedOptions>)
}
}

View File

@@ -28,6 +28,10 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
options: extension.options,
}
if (!extension.config.addGlobalAttributes) {
return
}
const globalAttributes = extension.config.addGlobalAttributes.bind(context)() as GlobalAttributes
globalAttributes.forEach(globalAttribute => {
@@ -53,6 +57,10 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
options: extension.options,
}
if (!extension.config.addAttributes) {
return
}
const attributes = extension.config.addAttributes.bind(context)() as Attributes
Object

View File

@@ -23,6 +23,3 @@ export { default as isCellSelection } from './helpers/isCellSelection'
export { default as findParentNodeClosestToPos } from './helpers/findParentNodeClosestToPos'
export interface Commands {}
// eslint-disable-next-line
export interface NodeSchemaFields<Options = any> {}

View File

@@ -14,9 +14,9 @@ import { Extension } from './Extension'
import { Node } from './Node'
import { Mark } from './Mark'
import { Editor } from './Editor'
import { Commands, NodeSchemaFields } from '.'
import { Commands } from '.'
export { Commands, NodeSchemaFields }
export { Commands }
export type Extensions = (Extension | Node | Mark)[]