UNPKG

@atlaskit/editor-plugin-annotation

Version:

Annotation plugin for @atlaskit/editor-core

225 lines (224 loc) 11.3 kB
import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } import _regeneratorRuntime from "@babel/runtime/regenerator"; import React from 'react'; import { isSSR } from '@atlaskit/editor-common/core-utils'; import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks'; import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments'; import { setInlineCommentDraftState, setSelectedAnnotation, setPendingSelectedAnnotation, showInlineCommentForBlockNode } from './editor-commands'; import { annotationWithToDOMFix } from './nodeviews/annotationMark'; import { inlineCommentPlugin } from './pm-plugins/inline-comment'; import { keymapPlugin } from './pm-plugins/keymap'; import { buildSuppressedToolbar, buildToolbar, shouldSuppressFloatingToolbar } from './pm-plugins/toolbar'; import { ACTIONS } from './pm-plugins/types'; import { getPluginState, hasAnyUnResolvedAnnotationInPage, inlineCommentPluginKey, stripNonExistingAnnotations } from './pm-plugins/utils'; import { InlineCommentView } from './ui/InlineCommentView'; import { getToolbarComponents } from './ui/toolbar-components'; export var annotationPlugin = function annotationPlugin(_ref) { var _api$featureFlags, _api$analytics; var annotationProviders = _ref.config, api = _ref.api; var featureFlags = api === null || api === void 0 || (_api$featureFlags = api.featureFlags) === null || _api$featureFlags === void 0 ? void 0 : _api$featureFlags.sharedState.currentState(); var isToolbarAIFCEnabled = Boolean(api === null || api === void 0 ? void 0 : api.toolbar); /** * Allows external editor UI, currently AI suggestions, to safely close an inline comment * without bypassing the provider's unsaved-content guard. */ var requestCloseInlineComment = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var _api$core$actions$exe, requestClose, canClose, _t; return _regeneratorRuntime.wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.prev = 0; requestClose = annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.requestClose; if (requestClose) { _context.next = 1; break; } return _context.abrupt("return", true); case 1: _context.next = 2; return requestClose(); case 2: canClose = _context.sent; if (canClose) { _context.next = 3; break; } return _context.abrupt("return", false); case 3: return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref3) { var tr = _ref3.tr; tr.setMeta(inlineCommentPluginKey, { type: ACTIONS.CLOSE_COMPONENT }); return tr; })) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false); case 4: _context.prev = 4; _t = _context["catch"](0); return _context.abrupt("return", false); case 5: case "end": return _context.stop(); } }, _callee, null, [[0, 4]]); })); return function requestCloseInlineComment() { return _ref2.apply(this, arguments); }; }(); if (isToolbarAIFCEnabled) { var _api$toolbar; api === null || api === void 0 || (_api$toolbar = api.toolbar) === null || _api$toolbar === void 0 || _api$toolbar.actions.registerComponents(getToolbarComponents(api, annotationProviders)); } return { name: 'annotation', marks: function marks() { return [{ name: 'annotation', mark: annotationWithToDOMFix }]; }, actions: { hasAnyUnResolvedAnnotationInPage: hasAnyUnResolvedAnnotationInPage, requestCloseInlineComment: requestCloseInlineComment, stripNonExistingAnnotations: stripNonExistingAnnotations, setInlineCommentDraftState: setInlineCommentDraftState(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions, annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes), showCommentForBlockNode: showInlineCommentForBlockNode(annotationProviders === null || annotationProviders === void 0 ? void 0 : annotationProviders.inlineComment.supportedBlockNodes), setSelectedAnnotation: setSelectedAnnotation, setPendingSelectedAnnotation: setPendingSelectedAnnotation }, getSharedState: function getSharedState(editorState) { if (!editorState) { return undefined; } var pluginState = getPluginState(editorState) || undefined; var clonedPluginState = Object.assign({}, pluginState); clonedPluginState === null || clonedPluginState === void 0 || delete clonedPluginState.featureFlagsPluginState; return clonedPluginState; }, pmPlugins: function pmPlugins() { return [{ name: 'annotation', plugin: function plugin(_ref4) { var dispatch = _ref4.dispatch; if (annotationProviders) { var _api$analytics2; return inlineCommentPlugin({ dispatch: dispatch, provider: annotationProviders.inlineComment, editorAnalyticsAPI: api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 ? void 0 : _api$analytics2.actions, featureFlagsPluginState: featureFlags, selectCommentExperience: annotationProviders.selectCommentExperience, viewInlineCommentTraceUFOPress: annotationProviders.viewInlineCommentTraceUFOPress, annotationManager: annotationProviders.annotationManager, api: api }); } return; } }, { name: 'annotationKeymap', plugin: function plugin() { if (annotationProviders) { return keymapPlugin(api); } return; } }]; }, pluginsOptions: { floatingToolbar: function floatingToolbar(state) { var pluginState = getPluginState(state); var bookmark = pluginState === null || pluginState === void 0 ? void 0 : pluginState.bookmark; if (shouldSuppressFloatingToolbar({ state: state, bookmark: bookmark })) { return buildSuppressedToolbar(state); } }, selectionToolbar: function selectionToolbar(state, intl) { if (isToolbarAIFCEnabled) { return; } if (!annotationProviders) { return; } var pluginState = getPluginState(state); if (pluginState && pluginState.isVisible && !pluginState.bookmark && !pluginState.mouseData.isSelecting) { var _api$analytics3; var _annotationProviders$ = annotationProviders.inlineComment, isToolbarAbove = _annotationProviders$.isToolbarAbove, onCommentButtonMount = _annotationProviders$.onCommentButtonMount, getCanAddComments = _annotationProviders$.getCanAddComments, contentType = _annotationProviders$.contentType; var toolbarConfig = buildToolbar(api === null || api === void 0 || (_api$analytics3 = api.analytics) === null || _api$analytics3 === void 0 ? void 0 : _api$analytics3.actions)({ state: state, intl: intl, isToolbarAbove: isToolbarAbove, api: api, createCommentExperience: annotationProviders.createCommentExperience, annotationManager: annotationProviders.annotationManager, onCommentButtonMount: onCommentButtonMount, getCanAddComments: getCanAddComments, contentType: contentType }); if (!toolbarConfig) { return undefined; } else { return _objectSpread(_objectSpread({}, toolbarConfig), {}, { rank: editorExperiment('platform_editor_controls', 'variant1') ? 1 : undefined }); } } } }, contentComponent: function contentComponent(_ref5) { var editorView = _ref5.editorView, dispatchAnalyticsEvent = _ref5.dispatchAnalyticsEvent; if (!annotationProviders || !editorView || isSSR()) { return null; } return /*#__PURE__*/React.createElement(AnnotationContentComponent, { api: api, editorView: editorView, annotationProviders: annotationProviders, dispatchAnalyticsEvent: dispatchAnalyticsEvent }); } }; }; var selector = function selector(states) { var _states$annotationSta, _states$annotationSta2, _states$annotationSta3; return { isVisible: (_states$annotationSta = states.annotationState) === null || _states$annotationSta === void 0 ? void 0 : _states$annotationSta.isVisible, selectedAnnotations: (_states$annotationSta2 = states.annotationState) === null || _states$annotationSta2 === void 0 ? void 0 : _states$annotationSta2.selectedAnnotations, annotations: (_states$annotationSta3 = states.annotationState) === null || _states$annotationSta3 === void 0 ? void 0 : _states$annotationSta3.annotations }; }; function AnnotationContentComponent(_ref6) { var _api$analytics4; var api = _ref6.api, editorView = _ref6.editorView, annotationProviders = _ref6.annotationProviders, dispatchAnalyticsEvent = _ref6.dispatchAnalyticsEvent; var annotationState = useSharedPluginStateWithSelector(api, ['annotation'], selector); // need to explicitly check for false as undefined is also a valid value to continue if ((annotationState === null || annotationState === void 0 ? void 0 : annotationState.isVisible) === false) { return null; } return /*#__PURE__*/React.createElement("div", { "data-editor-popup": "true" }, /*#__PURE__*/React.createElement(InlineCommentView, { providers: annotationProviders, editorView: editorView, dispatchAnalyticsEvent: dispatchAnalyticsEvent, editorAnalyticsAPI: api === null || api === void 0 || (_api$analytics4 = api.analytics) === null || _api$analytics4 === void 0 ? void 0 : _api$analytics4.actions, editorAPI: api })); }