UNPKG

@atlaskit/editor-core

Version:

A package contains Atlassian editor core functionality

100 lines (98 loc) 3.79 kB
import { sanitizeNodes } from '@atlaskit/adf-schema/schema'; import { sortByOrder } from '@atlaskit/editor-common/legacy-rank-plugins'; import { createProseMirrorMetadata } from '@atlaskit/editor-common/prosemirror-dom-metadata'; import { Schema } from '@atlaskit/editor-prosemirror/model'; import { fixExcludes } from './create-editor'; /** * 🧱 Internal Helper Function: Editor FE Platform * * Adds generic metadata attributes to a DOMOutputSpec array based on the provided node or mark. * This function ensures that the DOMOutputSpec is annotated with ProseMirror-specific metadata. * * @param {object} params - Parameters object. * @param {PMNode | PMMark} params.nodeOrMark - The ProseMirror node or mark to extract metadata from. * @param {DOMOutputSpec} params.domSpec - The DOMOutputSpec to which attributes will be added. * @returns {DOMOutputSpec} The modified DOMOutputSpec with additional metadata. */ export const addMetadataAttributes = ({ nodeOrMark, domSpec }) => { if (!Array.isArray(domSpec)) { return domSpec; } const maybeDefinedAttributes = domSpec[1]; const metadata = createProseMirrorMetadata(nodeOrMark); const hasDefinedAttributes = typeof maybeDefinedAttributes === 'object' && !Array.isArray(maybeDefinedAttributes); if (hasDefinedAttributes) { domSpec[1] = Object.assign(maybeDefinedAttributes, metadata); } else { domSpec.splice(1, 0, metadata); } return domSpec; }; /** * 🧱 Internal Helper Function: Editor FE Platform * * Wraps a `toDOM` function with a proxy that automatically adds metadata attributes * to the resulting DOMOutputSpec. This is useful for dynamically enhancing the output * of a `toDOM` function with additional context. * * @param {function(PMNode | PMMark): DOMOutputSpec} toDOM - The original `toDOM` function. * @returns {function(PMNode | PMMark): DOMOutputSpec} A proxied `toDOM` function that adds metadata attributes. */ export const wrapToDOMProxy = toDOM => { return new Proxy(toDOM, { apply(target, thisArg, argumentsList) { const domSpec = Reflect.apply(target, thisArg, argumentsList); if (!Array.isArray(domSpec)) { return domSpec; } const nodeOrMark = argumentsList[0]; return addMetadataAttributes({ nodeOrMark, domSpec }); } }); }; /** * 🧱 Internal Helper Function: Editor FE Platform * * Wraps a NodeSpec or MarkSpec object with a proxy to enhance its `toDOM` method. * This proxy automatically adds metadata attributes to the DOM output of the `toDOM` method, * enriching the DOM representation with additional ProseMirror-specific metadata. * * For nodes thats use NodeViews, you can find the implementation of those attributes on this file: * @see `packages/editor/editor-common/src/safe-plugin/index.ts` * * @template T * @param {T} spec - The NodeSpec or MarkSpec object to be wrapped. * @returns {T} A proxied NodeSpec or MarkSpec object where the `toDOM` method is enhanced * with metadata attributes. */ export const wrapNodeSpecProxy = spec => { return new Proxy(spec, { get(target, prop, receiver) { const result = Reflect.get(target, prop, receiver); if (prop === 'toDOM' && typeof result === 'function') { return wrapToDOMProxy(result); } return result; } }); }; export function createSchema(editorConfig) { const marks = fixExcludes(editorConfig.marks.sort(sortByOrder('marks')).reduce((acc, mark) => { acc[mark.name] = wrapNodeSpecProxy(mark.mark); return acc; }, {})); const nodes = sanitizeNodes(editorConfig.nodes.sort(sortByOrder('nodes')).reduce((acc, node) => { acc[node.name] = wrapNodeSpecProxy(node.node); return acc; }, {}), marks); return new Schema({ nodes, marks }); }