@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
119 lines (118 loc) • 4.3 kB
JavaScript
import { ErrorReporter } from '@atlaskit/editor-common/error-reporter';
import { sortByOrder } from '@atlaskit/editor-common/legacy-rank-plugins';
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
import { createEditorNativeAnchorSupportPlugin } from './editorNativeAnchorSupportPlugin';
import { createEditorStateNotificationPlugin } from './editorStateNotificationPlugin';
export function sortByRank(a, b) {
return a.rank - b.rank;
}
export function fixExcludes(marks) {
const markKeys = Object.keys(marks);
const markGroups = new Set(markKeys.map(mark => marks[mark].group));
markKeys.forEach(markKey => {
const mark = marks[markKey];
if (mark.excludes) {
// eslint-disable-next-line @atlassian/perf-linting/no-expensive-split-replace -- Ignored via go/ees017 (to be fixed)
mark.excludes = mark.excludes.split(' ').filter(group => markGroups.has(group)).join(' ');
}
});
return marks;
}
export function processPluginsList(plugins) {
/**
* First pass to collect pluginsOptions
*/
const pluginsOptions = plugins.reduce((acc, plugin) => {
if (plugin.pluginsOptions) {
Object.keys(plugin.pluginsOptions).forEach(pluginName => {
if (!acc[pluginName]) {
acc[pluginName] = [];
}
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
acc[pluginName].push(plugin.pluginsOptions[pluginName]);
});
}
return acc;
}, {});
/**
* Process plugins
*/
return plugins.reduce((acc, plugin) => {
if (plugin.pmPlugins) {
acc.pmPlugins.push(...plugin.pmPlugins(plugin.name ? pluginsOptions[plugin.name] : undefined));
}
if (plugin.nodes) {
acc.nodes.push(...plugin.nodes());
}
if (plugin.marks) {
acc.marks.push(...plugin.marks());
}
if (plugin.contentComponent) {
acc.contentComponents.push(plugin.contentComponent);
}
if (plugin.usePluginHook) {
// Wrap with .bind(null) so we can annotate the function with the
// plugin name without mutating the plugin's original hook reference.
// MountPluginHooks reads `pluginName` to derive a stable React key.
const named = plugin.usePluginHook.bind(null);
named.pluginName = plugin.name;
acc.pluginHooks.push(named);
}
if (plugin.primaryToolbarComponent) {
acc.primaryToolbarComponents.push(plugin.primaryToolbarComponent);
}
if (plugin.secondaryToolbarComponent) {
acc.secondaryToolbarComponents.push(plugin.secondaryToolbarComponent);
}
if (plugin.onEditorViewStateUpdated) {
acc.onEditorViewStateUpdatedCallbacks.push({
pluginName: plugin.name,
callback: plugin.onEditorViewStateUpdated
});
}
return acc;
}, {
nodes: [],
marks: [],
pmPlugins: [],
contentComponents: [],
pluginHooks: [],
primaryToolbarComponents: [],
secondaryToolbarComponents: [],
onEditorViewStateUpdatedCallbacks: []
});
}
export function createPMPlugins(config) {
const {
editorConfig
} = config;
const pmPlugins = editorConfig.pmPlugins.sort(sortByOrder('plugins')).map(({
plugin
}) => plugin({
schema: config.schema,
dispatch: config.dispatch,
eventDispatcher: config.eventDispatcher,
providerFactory: config.providerFactory,
errorReporter: config.errorReporter,
portalProviderAPI: config.portalProviderAPI,
nodeViewPortalProviderAPI: config.nodeViewPortalProviderAPI,
dispatchAnalyticsEvent: config.dispatchAnalyticsEvent,
featureFlags: config.featureFlags || {},
getIntl: config.getIntl
})).filter(plugin => typeof plugin !== 'undefined');
if (expValEquals('platform_editor_native_anchor_with_dnd', 'isEnabled', true)) {
pmPlugins.push(createEditorNativeAnchorSupportPlugin(config.schema));
}
if (config.onEditorStateUpdated !== undefined) {
return [createEditorStateNotificationPlugin(config.onEditorStateUpdated, config.editorConfig.onEditorViewStateUpdatedCallbacks), ...pmPlugins];
}
return pmPlugins;
}
export function createErrorReporter(errorReporterHandler) {
const errorReporter = new ErrorReporter();
if (errorReporterHandler) {
errorReporter.handler = errorReporterHandler;
}
return errorReporter;
}