@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
75 lines (72 loc) • 3 kB
JavaScript
import { Plugin } from '@atlaskit/editor-prosemirror/state';
import { fg } from '@atlaskit/platform-feature-flags';
import { createProseMirrorMetadata } from '../prosemirror-dom-metadata';
/**
* 🧱 Internal Helper Function: Editor FE Platform
*
* Attaches generic ProseMirror metadata attributes to a given DOM element based on the properties of a ProseMirror node.
* This function is useful for annotating DOM elements with metadata that describes the type and characteristics of the ProseMirror node.
*
*
* @param {Object} params - The parameters for the function.
* @param {PMNode} params.node - The ProseMirror node from which to derive metadata.
* @param {HTMLElement} params.dom - The DOM element to which the metadata attributes will be attached.
*/
export const attachGenericProseMirrorMetadata = ({
nodeOrMark,
dom
}) => {
const metadata = createProseMirrorMetadata(nodeOrMark);
Object.entries(metadata).forEach(([name, value]) => {
dom.setAttribute(name, value);
});
};
// Wraper to avoid any exception during the get pos operation
// See this https://hello.atlassian.net/wiki/spaces/EDITOR/pages/2849713193/ED-19672+Extensions+Regression
// And this https://discuss.prosemirror.net/t/possible-bug-on-viewdesc-posbeforechild/5783
const wrapGetPosExceptions = spec => {
var _spec$props;
if (!(spec !== null && spec !== void 0 && (_spec$props = spec.props) !== null && _spec$props !== void 0 && _spec$props.nodeViews)) {
return spec;
}
const unsafeNodeViews = spec.props.nodeViews;
const safeNodeViews = new Proxy(unsafeNodeViews, {
get(target, prop, receiver) {
const safeNodeView = new Proxy(Reflect.get(target, prop, receiver), {
apply(target, thisArg, argumentsList) {
const [node, view, unsafeGetPos, ...more] = argumentsList;
const safeGetPos = (() => {
try {
return unsafeGetPos();
} catch (e) {
return;
}
return;
// eslint-disable-next-line no-extra-bind
}).bind(thisArg);
const result = Reflect.apply(target, thisArg, [node, view, safeGetPos, ...more]);
if ((result === null || result === void 0 ? void 0 : result.dom) instanceof HTMLElement && fg('platform_editor_breakout_use_css')) {
attachGenericProseMirrorMetadata({
nodeOrMark: node,
dom: result.dom
});
}
return result;
}
});
return safeNodeView;
}
});
spec.props.nodeViews = safeNodeViews;
return spec;
};
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class SafePlugin extends Plugin {
// This variable isn't (and shouldn't) be used anywhere. Its purpose is
// to distinguish Plugin from SafePlugin, thus ensuring that an 'unsafe'
// Plugin cannot be assigned as an item in EditorPlugin → pmPlugins.
constructor(spec) {
super(wrapGetPosExceptions(spec));
}
}