// @ts-nocheck import { MarkSpec, NodeSpec, Schema } from "@sse-editor/pm/model"; import { Editor, MarkConfig, NodeConfig } from "../index.js"; import { AnyConfig, Extensions } from "../types.js"; import { callOrReturn } from "../utilities/callOrReturn.js"; import { isEmptyObject } from "../utilities/isEmptyObject.js"; import { getAttributesFromExtensions } from "./getAttributesFromExtensions.js"; import { getExtensionField } from "./getExtensionField.js"; import { getRenderedAttributes } from "./getRenderedAttributes.js"; import { injectExtensionAttributesToParseRule } from "./injectExtensionAttributesToParseRule.js"; import { splitExtensions } from "./splitExtensions.js"; function cleanUpSchemaItem(data: T) { return Object.fromEntries( // @ts-ignore Object.entries(data).filter(([key, value]) => { if (key === "attrs" && isEmptyObject(value as {} | undefined)) { return false; } return value !== null && value !== undefined; }) ) as T; } export function getSchemaByResolvedExtensions(extensions: Extensions, editor?: Editor): Schema { const allAttributes = getAttributesFromExtensions(extensions); const { nodeExtensions, markExtensions } = splitExtensions(extensions); const topNode = nodeExtensions.find((extension) => getExtensionField(extension, "topNode"))?.name; const nodes = Object.fromEntries( nodeExtensions.map((extension) => { const extensionAttributes = allAttributes.filter( (attribute) => attribute.type === extension.name ); const context = { name: extension.name, options: extension.options, storage: extension.storage, editor, }; const extraNodeFields = extensions.reduce((fields, e) => { const extendNodeSchema = getExtensionField( e, "extendNodeSchema", context ); return { ...fields, ...(extendNodeSchema ? extendNodeSchema(extension) : {}), }; }, {}); const schema: NodeSpec = cleanUpSchemaItem({ ...extraNodeFields, content: callOrReturn( getExtensionField(extension, "content", context) ), marks: callOrReturn(getExtensionField(extension, "marks", context)), group: callOrReturn(getExtensionField(extension, "group", context)), inline: callOrReturn(getExtensionField(extension, "inline", context)), atom: callOrReturn(getExtensionField(extension, "atom", context)), selectable: callOrReturn( getExtensionField(extension, "selectable", context) ), draggable: callOrReturn( getExtensionField(extension, "draggable", context) ), code: callOrReturn(getExtensionField(extension, "code", context)), defining: callOrReturn( getExtensionField(extension, "defining", context) ), isolating: callOrReturn( getExtensionField(extension, "isolating", context) ), attrs: Object.fromEntries( extensionAttributes.map((extensionAttribute) => { return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]; }) ), }); const parseHTML = callOrReturn( getExtensionField(extension, "parseHTML", context) ); // if (parseHTML) { // schema.parseDOM = parseHTML.map(parseRule => injectExtensionAttributesToParseRule(parseRule, extensionAttributes)) // } if (parseHTML) { schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes) ); } // if (parseHTML) { // schema.parseDOM = parseHTML.map((parseRule) => { // const modifiedRule = injectExtensionAttributesToParseRule(parseRule, extensionAttributes); // modifiedRule.tag = typeof modifiedRule.tag === "string" ? modifiedRule.tag : ""; // return { ...modifiedRule } as const; // }); // } const renderHTML = getExtensionField( extension, "renderHTML", context ); if (renderHTML) { schema.toDOM = (node) => renderHTML({ node, HTMLAttributes: getRenderedAttributes(node, extensionAttributes), }); } const renderText = getExtensionField( extension, "renderText", context ); if (renderText) { schema.toText = renderText; } return [extension.name, schema]; }) ); const marks = Object.fromEntries( markExtensions.map((extension) => { const extensionAttributes = allAttributes.filter( (attribute) => attribute.type === extension.name ); const context = { name: extension.name, options: extension.options, storage: extension.storage, editor, }; const extraMarkFields = extensions.reduce((fields, e) => { const extendMarkSchema = getExtensionField( e, "extendMarkSchema", context ); return { ...fields, ...(extendMarkSchema ? extendMarkSchema(extension) : {}), }; }, {}); const schema: MarkSpec = cleanUpSchemaItem({ ...extraMarkFields, inclusive: callOrReturn( getExtensionField(extension, "inclusive", context) ), excludes: callOrReturn( getExtensionField(extension, "excludes", context) ), group: callOrReturn(getExtensionField(extension, "group", context)), spanning: callOrReturn( getExtensionField(extension, "spanning", context) ), code: callOrReturn(getExtensionField(extension, "code", context)), attrs: Object.fromEntries( extensionAttributes.map((extensionAttribute) => { return [extensionAttribute.name, { default: extensionAttribute?.attribute?.default }]; }) ), }); const parseHTML = callOrReturn( getExtensionField(extension, "parseHTML", context) ); if (parseHTML) { schema.parseDOM = parseHTML.map((parseRule) => injectExtensionAttributesToParseRule(parseRule, extensionAttributes) ); } const renderHTML = getExtensionField( extension, "renderHTML", context ); if (renderHTML) { schema.toDOM = (mark) => renderHTML({ mark, HTMLAttributes: getRenderedAttributes(mark, extensionAttributes), }); } return [extension.name, schema]; }) ); return new Schema({ topNode, nodes, marks, }); }