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> { export class Extension<Options = any> {
type = 'extension' type = 'extension'
config: Required<ExtensionConfig> = { config: ExtensionConfig = {
name: 'extension', name: 'extension',
defaultOptions: {}, 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 options!: Options

View File

@@ -70,6 +70,10 @@ export default class ExtensionManager {
type: getSchemaTypeByName(extension.config.name, this.schema), type: getSchemaTypeByName(extension.config.name, this.schema),
} }
if (!extension.config.addCommands) {
return commands
}
return { return {
...commands, ...commands,
...extension.config.addCommands.bind(context)(), ...extension.config.addCommands.bind(context)(),
@@ -87,22 +91,36 @@ export default class ExtensionManager {
type: getSchemaTypeByName(extension.config.name, this.schema), type: getSchemaTypeByName(extension.config.name, this.schema),
} }
const keymapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)()) const plugins: Plugin[] = []
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)()
return [ if (extension.config.addKeyboardShortcuts) {
keymapPlugin, const keyMapPlugin = keymap(extension.config.addKeyboardShortcuts.bind(context)())
...inputRulePlugins,
...pasteRulePlugins, plugins.push(keyMapPlugin)
...plugins, }
]
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() .flat()
} }

View File

@@ -193,31 +193,9 @@ export interface MarkConfig<Options = any> extends Overwrite<ExtensionConfig<Opt
export class Mark<Options = any> { export class Mark<Options = any> {
type = 'mark' type = 'mark'
config: Required<MarkConfig> = { config: MarkConfig = {
name: 'mark', name: 'mark',
defaultOptions: {}, 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 options!: Options

View File

@@ -14,7 +14,6 @@ import {
NodeViewRenderer, NodeViewRenderer,
Overwrite, Overwrite,
RawCommands, RawCommands,
NodeSchemaFields,
} from './types' } from './types'
import { Editor } from './Editor' import { Editor } from './Editor'
@@ -257,45 +256,14 @@ export interface NodeConfig<Options = any> extends Overwrite<ExtensionConfig<Opt
export class Node<Options = any> { export class Node<Options = any> {
type = 'node' type = 'node'
config: Required<NodeConfig> & NodeSchemaFields<Options> = { config: NodeConfig = {
name: 'node', name: 'node',
defaultOptions: {}, 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 options!: Options
constructor(config: NodeConfig<Options> & NodeSchemaFields<Options>) { constructor(config: NodeConfig<Options>) {
this.config = { this.config = {
...this.config, ...this.config,
...config, ...config,
@@ -304,13 +272,13 @@ export class Node<Options = any> {
this.options = this.config.defaultOptions this.options = this.config.defaultOptions
} }
static create<O>(config: NodeConfig<O> & NodeSchemaFields<O>) { static create<O>(config: NodeConfig<O>) {
return new Node<O>(config) return new Node<O>(config)
} }
configure(options: Partial<Options> = {}) { configure(options: Partial<Options> = {}) {
return Node return Node
.create<Options>(this.config as (NodeConfig<Options> & NodeSchemaFields<Options>)) .create<Options>(this.config as NodeConfig<Options>)
.#configure(options) .#configure(options)
} }
@@ -320,10 +288,10 @@ export class Node<Options = any> {
return this return this
} }
extend<ExtendedOptions = Options>(extendedConfig: Partial<NodeConfig<ExtendedOptions> & NodeSchemaFields<ExtendedOptions>>) { extend<ExtendedOptions = Options>(extendedConfig: Partial<NodeConfig<ExtendedOptions>>) {
return new Node<ExtendedOptions>({ return new Node<ExtendedOptions>({
...this.config, ...this.config,
...extendedConfig, ...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, options: extension.options,
} }
if (!extension.config.addGlobalAttributes) {
return
}
const globalAttributes = extension.config.addGlobalAttributes.bind(context)() as GlobalAttributes const globalAttributes = extension.config.addGlobalAttributes.bind(context)() as GlobalAttributes
globalAttributes.forEach(globalAttribute => { globalAttributes.forEach(globalAttribute => {
@@ -53,6 +57,10 @@ export default function getAttributesFromExtensions(extensions: Extensions): Ext
options: extension.options, options: extension.options,
} }
if (!extension.config.addAttributes) {
return
}
const attributes = extension.config.addAttributes.bind(context)() as Attributes const attributes = extension.config.addAttributes.bind(context)() as Attributes
Object Object

View File

@@ -23,6 +23,3 @@ export { default as isCellSelection } from './helpers/isCellSelection'
export { default as findParentNodeClosestToPos } from './helpers/findParentNodeClosestToPos' export { default as findParentNodeClosestToPos } from './helpers/findParentNodeClosestToPos'
export interface Commands {} 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 { Node } from './Node'
import { Mark } from './Mark' import { Mark } from './Mark'
import { Editor } from './Editor' import { Editor } from './Editor'
import { Commands, NodeSchemaFields } from '.' import { Commands } from '.'
export { Commands, NodeSchemaFields } export { Commands }
export type Extensions = (Extension | Node | Mark)[] export type Extensions = (Extension | Node | Mark)[]

View File

@@ -66,7 +66,7 @@ declare module '@tiptap/core' {
} }
} }
interface NodeSchemaFields<Options> { interface NodeConfig<Options> {
/** /**
* Table Role * Table Role
*/ */
@@ -89,14 +89,6 @@ export const Table = Node.create<TableOptions>({
allowTableNodeSelection: false, allowTableNodeSelection: false,
}, },
extendNodeSchema(extension) {
const context = { options: extension.options }
return {
tableRole: callOrReturn(extension.config.tableRole, context),
}
},
content: 'tableRow+', content: 'tableRow+',
tableRole: 'table', tableRole: 'table',
@@ -265,4 +257,12 @@ export const Table = Node.create<TableOptions>({
}), }),
] ]
}, },
extendNodeSchema(extension) {
const context = { options: extension.options }
return {
tableRole: callOrReturn(extension.config.tableRole, context),
}
},
}) })