From 56df3bd3922a77fd6fd902ecdf6b1e010f4666f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Fri, 23 Oct 2020 22:55:48 +0200 Subject: [PATCH] implement basic parseHTML for global attributes --- packages/core/src/types.ts | 4 +- .../src/utils/getAttributesFromExtensions.ts | 2 +- packages/core/src/utils/getSchema.ts | 37 ++++++++++++++----- packages/extension-text-align/index.ts | 3 ++ 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index f816baf8..c7988c54 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -10,7 +10,9 @@ export type Attribute = { renderHTML?: (attributes: { [key: string]: any, }) => any, - parseHTML?: () => any, + parseHTML?: (node: HTMLElement) => { + [key: string]: any, + }, } export type Attributes = { diff --git a/packages/core/src/utils/getAttributesFromExtensions.ts b/packages/core/src/utils/getAttributesFromExtensions.ts index 4735a502..921d0b1e 100644 --- a/packages/core/src/utils/getAttributesFromExtensions.ts +++ b/packages/core/src/utils/getAttributesFromExtensions.ts @@ -15,7 +15,7 @@ export default function getAttributesFromExtensions(extensions: Extensions) { default: null, rendered: true, renderHTML: () => ({}), - parseHTML: () => null, + parseHTML: () => ({}), } extensions.forEach(extension => { diff --git a/packages/core/src/utils/getSchema.ts b/packages/core/src/utils/getSchema.ts index e14f23e9..0bf7251f 100644 --- a/packages/core/src/utils/getSchema.ts +++ b/packages/core/src/utils/getSchema.ts @@ -25,7 +25,7 @@ export default function getSchema(extensions: Extensions): Schema { options: extension.options, } - const attributes = allAttributes.filter(attribute => attribute.type === extension.name) + const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) const schema: NodeSpec = cleanUpSchemaItem({ content: extension.content, @@ -38,15 +38,34 @@ export default function getSchema(extensions: Extensions): Schema { code: extension.code, defining: extension.defining, isolating: extension.isolating, - attrs: Object.fromEntries(attributes.map(attribute => { - return [attribute.name, { default: attribute?.attribute?.default }] + attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { + return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] })), - parseDOM: extension.parseHTML.bind(context)(), + parseDOM: extension.parseHTML.bind(context)()?.map(parseRule => { + if (parseRule.style) { + return parseRule + } + + return { + ...parseRule, + getAttrs: node => { + const oldAttributes = parseRule.getAttrs ? parseRule.getAttrs(node) : {} + const newAttributes = extensionAttributes + .filter(item => item.attribute.rendered) + .reduce((items, item) => ({ + ...items, + ...item.attribute.parseHTML(node as HTMLElement), + }), {}) + + return { ...oldAttributes, ...newAttributes } + }, + } + }), ...(typeof extension.renderHTML === 'function') && { toDOM: node => { return (extension.renderHTML as Function).bind(context)({ node, - attributes: getRenderedAttributes(node, attributes), + attributes: getRenderedAttributes(node, extensionAttributes), }) }, }, @@ -60,22 +79,22 @@ export default function getSchema(extensions: Extensions): Schema { options: extension.options, } - const attributes = allAttributes.filter(attribute => attribute.type === extension.name) + const extensionAttributes = allAttributes.filter(attribute => attribute.type === extension.name) const schema: MarkSpec = cleanUpSchemaItem({ inclusive: extension.inclusive, excludes: extension.excludes, group: extension.group, spanning: extension.spanning, - attrs: Object.fromEntries(attributes.map(attribute => { - return [attribute.name, { default: attribute?.attribute?.default }] + attrs: Object.fromEntries(extensionAttributes.map(extensionAttribute => { + return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }] })), parseDOM: extension.parseHTML.bind(context)(), ...(typeof extension.renderHTML === 'function') && { toDOM: mark => { return (extension.renderHTML as Function).bind(context)({ mark, - attributes: getRenderedAttributes(mark, attributes), + attributes: getRenderedAttributes(mark, extensionAttributes), }) }, }, diff --git a/packages/extension-text-align/index.ts b/packages/extension-text-align/index.ts index ad6ffb7c..40a05e4f 100644 --- a/packages/extension-text-align/index.ts +++ b/packages/extension-text-align/index.ts @@ -21,6 +21,9 @@ const TextAlign = createExtension({ renderHTML: attributes => ({ style: `text-align: ${attributes.textAlign}`, }), + parseHTML: node => ({ + textAlign: node.style.textAlign, + }), }, }, },