tiptap/packages/core/src/helpers/getAttributesFromExtensions.ts

114 lines
2.8 KiB
TypeScript
Raw Normal View History

import { MarkConfig, NodeConfig } from '..'
import {
AnyConfig,
2020-10-22 05:55:14 +08:00
Attribute,
Attributes,
2020-10-22 05:55:14 +08:00
ExtensionAttribute,
Extensions,
GlobalAttributes,
} from '../types'
import { getExtensionField } from './getExtensionField'
import { splitExtensions } from './splitExtensions'
2020-10-27 20:19:23 +08:00
/**
* Get a list of all extension attributes defined in `addAttribute` and `addGlobalAttribute`.
* @param extensions List of extensions
*/
export function getAttributesFromExtensions(extensions: Extensions): ExtensionAttribute[] {
2020-10-22 15:42:28 +08:00
const extensionAttributes: ExtensionAttribute[] = []
2020-10-22 05:55:14 +08:00
const { nodeExtensions, markExtensions } = splitExtensions(extensions)
const nodeAndMarkExtensions = [...nodeExtensions, ...markExtensions]
const defaultAttribute: Required<Attribute> = {
default: null,
rendered: true,
renderHTML: null,
parseHTML: null,
2021-01-29 02:56:35 +08:00
keepOnSplit: true,
2022-03-23 09:01:35 +08:00
isRequired: false,
}
2020-10-22 05:55:14 +08:00
extensions.forEach(extension => {
2021-04-16 03:14:33 +08:00
const context = {
2021-04-21 05:11:35 +08:00
name: extension.name,
2020-10-22 05:55:14 +08:00
options: extension.options,
2021-10-22 14:52:54 +08:00
storage: extension.storage,
2021-04-16 03:14:33 +08:00
}
const addGlobalAttributes = getExtensionField<AnyConfig['addGlobalAttributes']>(
extension,
'addGlobalAttributes',
context,
)
2020-10-22 05:55:14 +08:00
2021-04-16 03:14:33 +08:00
if (!addGlobalAttributes) {
2021-02-19 17:54:47 +08:00
return
}
2021-04-16 03:14:33 +08:00
// TODO: remove `as GlobalAttributes`
const globalAttributes = addGlobalAttributes() as GlobalAttributes
2020-10-22 05:55:14 +08:00
globalAttributes.forEach(globalAttribute => {
globalAttribute.types.forEach(type => {
2020-10-22 15:42:28 +08:00
Object
.entries(globalAttribute.attributes)
.forEach(([name, attribute]) => {
extensionAttributes.push({
type,
name,
attribute: {
...defaultAttribute,
...attribute,
},
})
2020-10-22 05:55:14 +08:00
})
})
})
})
nodeAndMarkExtensions.forEach(extension => {
2021-04-16 03:14:33 +08:00
const context = {
2021-04-21 05:11:35 +08:00
name: extension.name,
options: extension.options,
2021-10-22 14:52:54 +08:00
storage: extension.storage,
2021-04-16 03:14:33 +08:00
}
const addAttributes = getExtensionField<NodeConfig['addAttributes'] | MarkConfig['addAttributes']>(
extension,
'addAttributes',
context,
)
2021-04-16 03:14:33 +08:00
if (!addAttributes) {
2021-02-19 17:54:47 +08:00
return
}
2021-04-16 03:14:33 +08:00
// TODO: remove `as Attributes`
const attributes = addAttributes() as Attributes
2020-10-22 15:42:28 +08:00
Object
.entries(attributes)
.forEach(([name, attribute]) => {
2022-03-23 09:01:35 +08:00
const mergedAttr = {
...defaultAttribute,
...attribute,
}
if (typeof mergedAttr?.default === 'function') {
mergedAttr.default = mergedAttr.default()
}
if (mergedAttr?.isRequired && mergedAttr?.default === undefined) {
2022-03-23 09:09:30 +08:00
delete mergedAttr.default
2022-03-23 09:01:35 +08:00
}
2022-03-23 09:09:30 +08:00
2020-10-22 15:42:28 +08:00
extensionAttributes.push({
2021-04-16 05:14:47 +08:00
type: extension.name,
2020-10-22 15:42:28 +08:00
name,
2022-03-23 09:01:35 +08:00
attribute: mergedAttr,
2022-03-23 09:09:30 +08:00
})
})
})
2020-10-22 15:42:28 +08:00
return extensionAttributes
}