add optional callback functions to schema fields

This commit is contained in:
Philipp Kühn 2020-10-30 15:20:10 +01:00
parent b28a322d8b
commit 073ef2ee0d
5 changed files with 49 additions and 34 deletions

View File

@ -10,22 +10,22 @@ export interface MarkExtensionSpec<Options = {}, Commands = {}> extends Overwrit
/** /**
* Inclusive * Inclusive
*/ */
inclusive?: MarkSpec['inclusive'], inclusive?: MarkSpec['inclusive'] | ((this: { options: Options }) => MarkSpec['inclusive']),
/** /**
* Excludes * Excludes
*/ */
excludes?: MarkSpec['excludes'], excludes?: MarkSpec['excludes'] | ((this: { options: Options }) => MarkSpec['excludes']),
/** /**
* Group * Group
*/ */
group?: MarkSpec['group'], group?: MarkSpec['group'] | ((this: { options: Options }) => MarkSpec['group']),
/** /**
* Spanning * Spanning
*/ */
spanning?: MarkSpec['spanning'], spanning?: MarkSpec['spanning'] | ((this: { options: Options }) => MarkSpec['spanning']),
/** /**
* Parse HTML * Parse HTML

View File

@ -15,52 +15,52 @@ export interface NodeExtensionSpec<Options = {}, Commands = {}> extends Overwrit
/** /**
* Content * Content
*/ */
content?: NodeSpec['content'], content?: NodeSpec['content'] | ((this: { options: Options }) => NodeSpec['content']),
/** /**
* Marks * Marks
*/ */
marks?: NodeSpec['marks'], marks?: NodeSpec['marks'] | ((this: { options: Options }) => NodeSpec['marks']),
/** /**
* Group * Group
*/ */
group?: NodeSpec['group'], group?: NodeSpec['group'] | ((this: { options: Options }) => NodeSpec['group']),
/** /**
* Inline * Inline
*/ */
inline?: NodeSpec['inline'], inline?: NodeSpec['inline'] | ((this: { options: Options }) => NodeSpec['inline']),
/** /**
* Atom * Atom
*/ */
atom?: NodeSpec['atom'], atom?: NodeSpec['atom'] | ((this: { options: Options }) => NodeSpec['atom']),
/** /**
* Selectable * Selectable
*/ */
selectable?: NodeSpec['selectable'], selectable?: NodeSpec['selectable'] | ((this: { options: Options }) => NodeSpec['selectable']),
/** /**
* Draggable * Draggable
*/ */
draggable?: NodeSpec['draggable'], draggable?: NodeSpec['draggable'] | ((this: { options: Options }) => NodeSpec['draggable']),
/** /**
* Code * Code
*/ */
code?: NodeSpec['code'], code?: NodeSpec['code'] | ((this: { options: Options }) => NodeSpec['code']),
/** /**
* Defining * Defining
*/ */
defining?: NodeSpec['defining'], defining?: NodeSpec['defining'] | ((this: { options: Options }) => NodeSpec['defining']),
/** /**
* Isolating * Isolating
*/ */
isolating?: NodeSpec['isolating'], isolating?: NodeSpec['isolating'] | ((this: { options: Options }) => NodeSpec['isolating']),
/** /**
* Parse HTML * Parse HTML

View File

@ -0,0 +1,17 @@
/**
* Optionally calls `value` as a function.
* Otherwise it is returned directly.
* @param value Function or any value.
* @param context Optional context to bind to function.
*/
export default function callOrReturn(value: any, context?: any) {
if (typeof value === 'function') {
if (context) {
return value.bind(context)()
}
return value()
}
return value
}

View File

@ -5,6 +5,7 @@ import getAttributesFromExtensions from './getAttributesFromExtensions'
import getRenderedAttributes from './getRenderedAttributes' import getRenderedAttributes from './getRenderedAttributes'
import isEmptyObject from './isEmptyObject' import isEmptyObject from './isEmptyObject'
import injectExtensionAttributesToParseRule from './injectExtensionAttributesToParseRule' import injectExtensionAttributesToParseRule from './injectExtensionAttributesToParseRule'
import callOrReturn from './callOrReturn'
function cleanUpSchemaItem<T>(data: T) { function cleanUpSchemaItem<T>(data: T) {
return Object.fromEntries(Object.entries(data).filter(([key, value]) => { return Object.fromEntries(Object.entries(data).filter(([key, value]) => {
@ -25,16 +26,16 @@ export default function getSchema(extensions: Extensions): Schema {
const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name)
const context = { options: extension.options } const context = { options: extension.options }
const schema: NodeSpec = cleanUpSchemaItem({ const schema: NodeSpec = cleanUpSchemaItem({
content: extension.content, content: callOrReturn(extension.content, context),
marks: extension.marks, marks: callOrReturn(extension.marks, context),
group: extension.group, group: callOrReturn(extension.group, context),
inline: extension.inline, inline: callOrReturn(extension.inline, context),
atom: extension.atom, atom: callOrReturn(extension.atom, context),
selectable: extension.selectable, selectable: callOrReturn(extension.selectable, context),
draggable: extension.draggable, draggable: callOrReturn(extension.draggable, context),
code: extension.code, code: callOrReturn(extension.code, context),
defining: extension.defining, defining: callOrReturn(extension.defining, context),
isolating: extension.isolating, isolating: callOrReturn(extension.isolating, context),
attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
})), })),
@ -60,10 +61,10 @@ export default function getSchema(extensions: Extensions): Schema {
const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name)
const context = { options: extension.options } const context = { options: extension.options }
const schema: MarkSpec = cleanUpSchemaItem({ const schema: MarkSpec = cleanUpSchemaItem({
inclusive: extension.inclusive, inclusive: callOrReturn(extension.inclusive, context),
excludes: extension.excludes, excludes: callOrReturn(extension.excludes, context),
group: extension.group, group: callOrReturn(extension.group, context),
spanning: extension.spanning, spanning: callOrReturn(extension.spanning, context),
attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => {
return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]
})), })),

View File

@ -7,12 +7,9 @@ export interface TaskItemOptions {
const TaskItem = createNode({ const TaskItem = createNode({
name: 'task_item', name: 'task_item',
content: 'paragraph+', content() {
return this.options.nested ? '(paragraph|task_list)+' : 'paragraph+'
// TODO: allow content to be a callback function },
// content() {
// return this.options.nested ? '(paragraph|todo_list)+' : 'paragraph+',
// },
defining: true, defining: true,