@atlaskit/editor-plugin-extension
Version:
editor-plugin-extension plugin for @atlaskit/editor-core
193 lines • 8.39 kB
JavaScript
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
import uuid from 'uuid/v4';
import { extension, extensionFrame, inlineExtension, multiBodiedExtension } from '@atlaskit/adf-schema';
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
import { fg } from '@atlaskit/platform-feature-flags';
import { createEditSelectedExtensionAction, insertOrReplaceBodiedExtension, insertOrReplaceExtension } from './editor-actions/actions';
import { forceAutoSave } from './editor-commands/commands';
import { createExtensionAPI } from './pm-plugins/extension-api';
import keymapPlugin from './pm-plugins/keymap';
import { insertMacroFromMacroBrowser, runMacroAutoConvert } from './pm-plugins/macro/actions';
import { createPlugin as createMacroPlugin } from './pm-plugins/macro/plugin';
import { createPlugin } from './pm-plugins/main';
import { pluginKey } from './pm-plugins/plugin-key';
import { bodiedExtensionSpecWithFixedToDOM } from './pm-plugins/toDOM-fixes/bodiedExtension';
import { getToolbarConfig } from './pm-plugins/toolbar';
import { createPlugin as createUniqueIdPlugin } from './pm-plugins/unique-id';
// Remove below line when cleaning up platform_editor_ai_object_sidebar_injection feature flag
import { CONFIG_PANEL_ID } from './ui/ConfigPanel/constants';
import { getContextPanel } from './ui/context-panel';
import { useConfigPanelPluginHook } from './ui/useConfigPanelPluginHook';
export const extensionPlugin = ({
config: options = {},
api
}) => {
var _api$featureFlags, _api$contextPanel, _api$contextPanel$act, _api$analytics2, _api$analytics3, _api$contextPanel4;
// eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead
const configPanelId = `${CONFIG_PANEL_ID}-${uuid()}`;
const featureFlags = (api === null || api === void 0 ? void 0 : (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState()) || {};
//Note: This is a hack to get the editor view reference in the plugin. Copied from table plugin.
//This is needed to get the current selection in the editor
const editorViewRef = {
current: null
};
const showContextPanel = api === null || api === void 0 ? void 0 : (_api$contextPanel = api.contextPanel) === null || _api$contextPanel === void 0 ? void 0 : (_api$contextPanel$act = _api$contextPanel.actions) === null || _api$contextPanel$act === void 0 ? void 0 : _api$contextPanel$act.showPanel;
return {
name: 'extension',
nodes() {
const extensionNodes = [{
name: 'extension',
node: extension
}, {
name: 'bodiedExtension',
node: bodiedExtensionSpecWithFixedToDOM()
}, {
name: 'inlineExtension',
node: inlineExtension
}, {
name: 'extensionFrame',
node: extensionFrame
}, {
name: 'multiBodiedExtension',
node: multiBodiedExtension
}];
return extensionNodes;
},
getSharedState(state) {
if (!state) {
return undefined;
}
const pluginState = pluginKey.getState(state);
return {
showContextPanel: pluginState === null || pluginState === void 0 ? void 0 : pluginState.showContextPanel,
extensionProvider: pluginState === null || pluginState === void 0 ? void 0 : pluginState.extensionProvider,
processParametersAfter: pluginState === null || pluginState === void 0 ? void 0 : pluginState.processParametersAfter
};
},
pmPlugins() {
return [{
name: 'extension',
plugin: ({
dispatch,
providerFactory,
portalProviderAPI,
eventDispatcher
}) => {
const extensionHandlers = options.extensionHandlers || {};
return createPlugin(dispatch, providerFactory, extensionHandlers, portalProviderAPI, eventDispatcher, api, options.useLongPressSelection, {
appearance: options.appearance,
getExtensionHeight: options.getExtensionHeight
}, featureFlags, options === null || options === void 0 ? void 0 : options.__rendererExtensionOptions);
}
}, {
name: 'extensionKeymap',
plugin: () => {
var _api$contextPanel2;
return keymapPlugin(api === null || api === void 0 ? void 0 : (_api$contextPanel2 = api.contextPanel) === null || _api$contextPanel2 === void 0 ? void 0 : _api$contextPanel2.actions.applyChange);
}
}, {
name: 'extensionUniqueId',
plugin: () => createUniqueIdPlugin()
}, {
name: 'extensionEditorViewRef',
plugin: () => {
return new SafePlugin({
view: editorView => {
// Do not cleanup the editorViewRef on destroy
// because some functions may point to a stale
// reference and this means we will return null.
// EditorView is assumed to be stable so we do not need to
// cleanup.
// See: #hot-106316
editorViewRef.current = editorView;
return {};
}
});
}
}, {
name: 'macro',
plugin: ({
dispatch,
providerFactory
}) => createMacroPlugin(dispatch, providerFactory)
}];
},
actions: {
api: () => {
var _api$contextPanel3, _api$analytics;
return createExtensionAPI({
// Ignored via go/ees005
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
editorView: editorViewRef.current,
applyChange: api === null || api === void 0 ? void 0 : (_api$contextPanel3 = api.contextPanel) === null || _api$contextPanel3 === void 0 ? void 0 : _api$contextPanel3.actions.applyChange,
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions
});
},
insertMacroFromMacroBrowser: insertMacroFromMacroBrowser(api === null || api === void 0 ? void 0 : (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions),
insertOrReplaceExtension: ({
editorView,
action,
attrs,
content,
position,
size,
tr
}) => insertOrReplaceExtension({
editorView,
action,
attrs,
content,
position,
size,
tr
}),
insertOrReplaceBodiedExtension: ({
editorView,
action,
attrs,
content,
position,
size,
tr
}) => insertOrReplaceBodiedExtension({
editorView,
action,
attrs,
content,
position,
size,
tr
}),
editSelectedExtension: createEditSelectedExtensionAction({
editorViewRef,
editorAnalyticsAPI: api === null || api === void 0 ? void 0 : (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions,
applyChangeToContextPanel: api === null || api === void 0 ? void 0 : (_api$contextPanel4 = api.contextPanel) === null || _api$contextPanel4 === void 0 ? void 0 : _api$contextPanel4.actions.applyChange
}),
runMacroAutoConvert,
forceAutoSave
},
pluginsOptions: {
floatingToolbar: getToolbarConfig({
breakoutEnabled: options.breakoutEnabled,
extensionApi: api,
getUnsupportedContent: options.getUnsupportedContent
}),
contextPanel:
// if showContextPanel action is not available, or platform_editor_ai_object_sidebar_injection feature flag is off
// then keep using old context panel.
!showContextPanel || !fg('platform_editor_ai_object_sidebar_injection') ? getContextPanel(() => {
var _editorViewRef$curren;
return (_editorViewRef$curren = editorViewRef.current) !== null && _editorViewRef$curren !== void 0 ? _editorViewRef$curren : undefined;
})(api, featureFlags) : undefined
},
usePluginHook: showContextPanel && fg('platform_editor_ai_object_sidebar_injection') ? ({
editorView
}) => {
useConfigPanelPluginHook({
api,
configPanelId,
editorView
});
} : undefined
};
};