UNPKG

@atlaskit/editor-plugin-mentions

Version:

Mentions plugin for @atlaskit/editor-core

276 lines (275 loc) 12.5 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, { useEffect, useMemo } from 'react'; import { useIntl } from 'react-intl'; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead import uuid from 'uuid'; import { INPUT_METHOD } from '@atlaskit/editor-common/analytics'; import { toolbarInsertBlockMessages as messages, mentionMessages } from '@atlaskit/editor-common/messages'; import { WithProviders } from '@atlaskit/editor-common/provider-factory'; import { IconMention } from '@atlaskit/editor-common/quick-insert'; import { isResolvingMentionProvider } from '@atlaskit/mention/resource'; import { MentionNameStatus, isPromise } from '@atlaskit/mention/types'; import { fg } from '@atlaskit/platform-feature-flags'; import { insertMention } from './editor-commands'; import { mentionNodeSpec } from './nodeviews/mentionNodeSpec'; import { mentionPluginKey } from './pm-plugins/key'; import { ACTIONS, createMentionPlugin } from './pm-plugins/main'; import { createMentionPlaceholderPlugin } from './pm-plugins/mentionPlaceholder'; import { InlineInviteRecaptchaContainer } from './ui/InlineInviteRecaptchaContainer'; import { SecondaryToolbarComponent } from './ui/SecondaryToolbarComponent'; import { createTypeAheadConfig } from './ui/type-ahead'; var processName = function processName(name, intl) { var unknownLabel = intl.formatMessage(mentionMessages.unknownLabel); if (name.status === MentionNameStatus.OK) { return "@".concat(name.name || unknownLabel); } else { return "@".concat(unknownLabel); } }; /** * We will need to clean this up once mentionProvider is * put inside mention plugin. * See: https://product-fabric.atlassian.net/browse/ED-26011 */ function Component(_ref) { var mentionProvider = _ref.mentionProvider, api = _ref.api; var mentionProviderMemo = useMemo(function () { return mentionProvider; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); var intl = useIntl(); useEffect(function () { mentionProviderMemo === null || mentionProviderMemo === void 0 || mentionProviderMemo.then(function (mentionProviderSync) { var _api$base; api === null || api === void 0 || (_api$base = api.base) === null || _api$base === void 0 || (_api$base = _api$base.actions) === null || _api$base === void 0 || _api$base.registerMarks(function (_ref2) { var tr = _ref2.tr, node = _ref2.node, pos = _ref2.pos; var doc = tr.doc; var schema = doc.type.schema; var mentionNodeType = schema.nodes.mention; var id = node.attrs.id; if (node.type === mentionNodeType) { if (isResolvingMentionProvider(mentionProviderSync)) { var nameDetail = mentionProviderSync === null || mentionProviderSync === void 0 ? void 0 : mentionProviderSync.resolveMentionName(id); var newText; if (isPromise(nameDetail)) { newText = "@".concat(intl.formatMessage(mentionMessages.unknownLabel)); } else { newText = processName(nameDetail, intl); } var currentPos = tr.mapping.map(pos); tr.replaceWith(currentPos, currentPos + node.nodeSize, schema.text(newText, node.marks)); } } }); }); }, [mentionProviderMemo, api, intl]); return null; } var mentionsPlugin = function mentionsPlugin(_ref3) { var _options$sanitizePriv, _options$insertDispla; var options = _ref3.config, api = _ref3.api; // eslint-disable-next-line @atlaskit/platform/prefer-crypto-random-uuid -- Use crypto.randomUUID instead var sessionId = uuid(); var previousMediaProvider; var fireEvent = function fireEvent(payload, channel) { var _api$analytics; var fireAnalyticsEvent = api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || (_api$analytics = _api$analytics.actions) === null || _api$analytics === void 0 ? void 0 : _api$analytics.fireAnalyticsEvent; if (!fireAnalyticsEvent) { return; } if (payload.attributes && !payload.attributes.sessionId) { payload.attributes.sessionId = sessionId; } fireAnalyticsEvent(payload, channel); }; var typeAhead = createTypeAheadConfig({ sanitizePrivateContent: options === null || options === void 0 ? void 0 : options.sanitizePrivateContent, mentionInsertDisplayName: options === null || options === void 0 ? void 0 : options.insertDisplayName, HighlightComponent: options === null || options === void 0 ? void 0 : options.HighlightComponent, handleMentionsChanged: options === null || options === void 0 ? void 0 : options.handleMentionsChanged, fireEvent: fireEvent, api: api }); return { name: 'mention', nodes: function nodes() { return [{ name: 'mention', node: mentionNodeSpec() }]; }, pmPlugins: function pmPlugins() { var plugins = [{ name: 'mention', plugin: function plugin(pmPluginFactoryParams) { return createMentionPlugin({ pmPluginFactoryParams: pmPluginFactoryParams, fireEvent: fireEvent, options: options, api: api }); } }]; if (fg('jira_invites_auto_tag_new_user_in_mentions_fg')) { plugins.push({ name: 'mentionPlaceholder', plugin: function plugin() { return createMentionPlaceholderPlugin(); } }); } return plugins; }, contentComponent: function contentComponent(_ref4) { var editorView = _ref4.editorView, providerFactory = _ref4.providerFactory; if (!editorView) { return null; } return /*#__PURE__*/React.createElement(WithProviders // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , { providers: ['mentionProvider'], providerFactory: providerFactory // eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed) , renderNode: function renderNode(_ref5) { var mentionProvider = _ref5.mentionProvider; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Component, { mentionProvider: mentionProvider, api: api }), fg('jira_invites_auto_tag_new_user_in_mentions_fg') && /*#__PURE__*/React.createElement(InlineInviteRecaptchaContainer, { mentionProvider: mentionProvider, api: api })); } }); }, secondaryToolbarComponent: function secondaryToolbarComponent(_ref6) { var editorView = _ref6.editorView, disabled = _ref6.disabled; if (!editorView) { return null; } return /*#__PURE__*/React.createElement(SecondaryToolbarComponent, { editorView: editorView, api: api, disabled: disabled, typeAhead: typeAhead }); }, commands: { insertMention: insertMention({ sanitizePrivateContent: (_options$sanitizePriv = options === null || options === void 0 ? void 0 : options.sanitizePrivateContent) !== null && _options$sanitizePriv !== void 0 ? _options$sanitizePriv : false, mentionInsertDisplayName: (_options$insertDispla = options === null || options === void 0 ? void 0 : options.insertDisplayName) !== null && _options$insertDispla !== void 0 ? _options$insertDispla : false, api: api }) }, actions: { openTypeAhead: function openTypeAhead(inputMethod) { var _api$typeAhead; return Boolean(api === null || api === void 0 || (_api$typeAhead = api.typeAhead) === null || _api$typeAhead === void 0 || (_api$typeAhead = _api$typeAhead.actions) === null || _api$typeAhead === void 0 ? void 0 : _api$typeAhead.open({ triggerHandler: typeAhead, inputMethod: inputMethod })); }, announceMentionsInsertion: function announceMentionsInsertion(mentionChanges) { if (options !== null && options !== void 0 && options.handleMentionsChanged) { options.handleMentionsChanged(mentionChanges); } }, setProvider: function () { var _setProvider = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(providerPromise) { var _api$core$actions$exe; var provider; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (fg('platform_editor_mention_provider_via_plugin_config')) { _context.next = 2; break; } return _context.abrupt("return", false); case 2: _context.next = 4; return providerPromise; case 4: provider = _context.sent; if (!(previousMediaProvider === provider)) { _context.next = 7; break; } return _context.abrupt("return", false); case 7: previousMediaProvider = provider; return _context.abrupt("return", (_api$core$actions$exe = api === null || api === void 0 ? void 0 : api.core.actions.execute(function (_ref7) { var tr = _ref7.tr; return tr.setMeta(mentionPluginKey, { action: ACTIONS.SET_PROVIDER, params: { provider: provider } }); })) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false); case 9: case "end": return _context.stop(); } }, _callee); })); function setProvider(_x) { return _setProvider.apply(this, arguments); } return setProvider; }() }, getSharedState: function getSharedState(editorState) { if (!editorState) { return undefined; } var mentionPluginState = mentionPluginKey.getState(editorState); return _objectSpread(_objectSpread({}, mentionPluginState), {}, { typeAheadHandler: typeAhead }); }, pluginsOptions: { quickInsert: function quickInsert(_ref8) { var formatMessage = _ref8.formatMessage; return [{ id: 'mention', title: formatMessage(messages.mention), description: formatMessage(messages.mentionDescription), keywords: ['team', 'user'], priority: 400, keyshortcut: '@', icon: function icon() { return /*#__PURE__*/React.createElement(IconMention, null); }, action: function action(insert, state) { var _api$typeAhead2; var tr = insert(undefined); var pluginState = mentionPluginKey.getState(state); if (pluginState && pluginState.canInsertMention === false) { return false; } api === null || api === void 0 || (_api$typeAhead2 = api.typeAhead) === null || _api$typeAhead2 === void 0 || _api$typeAhead2.actions.openAtTransaction({ triggerHandler: typeAhead, inputMethod: INPUT_METHOD.QUICK_INSERT })(tr); return tr; } }]; }, typeAhead: typeAhead } }; }; export { mentionsPlugin };