@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
100 lines (98 loc) • 3.79 kB
JavaScript
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
});
}