UNPKG

@atlaskit/editor-plugin-mentions

Version:

Mentions plugin for @atlaskit/editor-core

250 lines (247 loc) 11.2 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ACTIONS = void 0; exports.createMentionPlugin = createMentionPlugin; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _analytics = require("@atlaskit/editor-common/analytics"); var _safePlugin = require("@atlaskit/editor-common/safe-plugin"); var _insm = require("@atlaskit/insm"); var _analytics2 = require("@atlaskit/mention/analytics"); var _types = require("@atlaskit/mention/types"); var _fg = require("@atlaskit/platform-feature-flags/fg"); var _isMentionTypeAheadEnabled = require("../isMentionTypeAheadEnabled"); var _mentionNodeView = require("../nodeviews/mentionNodeView"); var _types2 = require("../types"); var _key = require("./key"); var _utils = require("./utils"); 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) { (0, _defineProperty2.default)(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; } var ACTIONS = exports.ACTIONS = { COMMIT_PENDING_TYPED_AGENT_MENTION: 'COMMIT_PENDING_TYPED_AGENT_MENTION', DISCARD_PENDING_TYPED_AGENT_MENTION: 'DISCARD_PENDING_TYPED_AGENT_MENTION', SET_PENDING_TYPED_AGENT_MENTION: 'SET_PENDING_TYPED_AGENT_MENTION', SET_PROVIDER: 'SET_PROVIDER', /** * Dispatched by the `setAgentMentionRunStates` action to push the product's run-state * map into plugin state, which drives the run-state node decorations. */ SET_AGENT_RUN_STATES: 'SET_AGENT_RUN_STATES', /** * Dispatched from view().update() when async resolveMentionName() resolves * for a pasted agent mention. * Updates lastInsertedAgentMentionName so the nudge shows the correct name. */ RESOLVE_PASTED_AGENT_MENTION_NAME: 'RESOLVE_PASTED_AGENT_MENTION_NAME', /** * Dispatched from view().update() when async resolveMentionName() resolves * with a non-OK status for a pasted agent mention. * Clears pendingPastedAgentMention so no retry loop occurs. */ CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION' }; var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions"; var PACKAGE_VERSION = "21.0.2"; var setProvider = function setProvider(provider) { return function (state, dispatch) { if (dispatch) { dispatch(state.tr.setMeta(_key.mentionPluginKey, { action: ACTIONS.SET_PROVIDER, params: { provider: provider } })); } return true; }; }; function createMentionPlugin(_ref) { var pmPluginFactoryParams = _ref.pmPluginFactoryParams, fireEvent = _ref.fireEvent, options = _ref.options, api = _ref.api; var mentionProvider; var isMentionInsertionEnabled = function isMentionInsertionEnabled(state) { return (0, _isMentionTypeAheadEnabled.isMentionTypeAheadEnabled)(options === null || options === void 0 ? void 0 : options.canOpenTypeAhead) && (0, _utils.canMentionBeCreatedInRange)(state.selection.from, state.selection.to)(state); }; var sendAnalytics = function sendAnalytics(event, actionSubject, action, attributes) { if (event === _analytics2.SLI_EVENT_TYPE || event === _analytics2.SMART_EVENT_TYPE) { fireEvent({ action: action, actionSubject: actionSubject, eventType: _analytics.EVENT_TYPE.OPERATIONAL, attributes: _objectSpread({ packageName: PACKAGE_NAME, packageVersion: PACKAGE_VERSION, componentName: _types.ComponentNames.MENTION }, attributes) }, 'fabricElements'); } }; return new _safePlugin.SafePlugin({ key: _key.mentionPluginKey, state: { init: function init(_, state) { return { canInsertMention: isMentionInsertionEnabled(state) }; }, apply: function apply(tr, pluginState, oldState, newState) { var _ref2 = tr.getMeta(_key.mentionPluginKey) || { action: null, params: null }, action = _ref2.action, params = _ref2.params; var hasPublicPluginStateChanged = false; var newPluginState = pluginState; var hasPositionChanged = oldState.selection.from !== newState.selection.from || oldState.selection.to !== newState.selection.to; if (tr.docChanged || tr.selectionSet && hasPositionChanged) { newPluginState = _objectSpread(_objectSpread({}, pluginState), {}, { canInsertMention: isMentionInsertionEnabled(newState) }); hasPublicPluginStateChanged = true; } switch (action) { case ACTIONS.SET_PROVIDER: newPluginState = _objectSpread(_objectSpread({}, newPluginState), {}, { mentionProvider: params.provider }); hasPublicPluginStateChanged = true; break; } if (hasPublicPluginStateChanged) { pmPluginFactoryParams.dispatch(_key.mentionPluginKey, newPluginState); } if (options !== null && options !== void 0 && options.handleMentionsChanged && tr.docChanged) { var _insm$session, _insm$session2; (_insm$session = _insm.insm.session) === null || _insm$session === void 0 || _insm$session.startFeature('mentionDeletionDetection'); var mentionSchema = newState.schema.nodes.mention; var mentionsRemoved = new Map(); tr.steps.forEach(function (step, index) { step.getMap().forEach(function (from, to) { var newStart = tr.mapping.slice(index).map(from, -1); var newEnd = tr.mapping.slice(index).map(to); var oldStart = tr.mapping.invert().map(newStart, -1); var oldEnd = tr.mapping.invert().map(newEnd); var oldSlice = oldState.doc.slice(oldStart, oldEnd); var newSlice = newState.doc.slice(newStart, newEnd); var mentionsBefore = new Map(); var mentionsAfter = new Map(); oldSlice.content.descendants(function (node) { if (node.type.name === mentionSchema.name && node.attrs.localId) { mentionsBefore.set(node.attrs.localId, { id: node.attrs.id, localId: node.attrs.localId }); } }); newSlice.content.descendants(function (node) { if (node.type.name === mentionSchema.name && node.attrs.localId) { mentionsAfter.set(node.attrs.localId, { id: node.attrs.id, localId: node.attrs.localId }); } }); // Determine which mentions were removed in this step mentionsBefore.forEach(function (mention, localId) { if (!mentionsAfter.has(localId)) { mentionsRemoved.set(localId, mention); } }); // Adjust mentionsRemoved by removing any that reappear mentionsAfter.forEach(function (_, localId) { if (mentionsRemoved.has(localId)) { mentionsRemoved.delete(localId); } }); }); }); if (mentionsRemoved.size > 0) { var changes = Array.from(mentionsRemoved.values()).map(function (mention) { return { id: mention.id, localId: mention.localId, type: 'deleted' }; }); options.handleMentionsChanged(changes); } (_insm$session2 = _insm.insm.session) === null || _insm$session2 === void 0 || _insm$session2.endFeature('mentionDeletionDetection'); } return newPluginState; } }, props: { nodeViews: { mention: function mention(node, view) { return new _mentionNodeView.MentionNodeView(node, { options: options, api: api, editorView: view, portalProviderAPI: pmPluginFactoryParams.portalProviderAPI }); } } }, view: function view(editorView) { var providerHandler = function providerHandler(name, providerPromise) { switch (name) { case 'mentionProvider': if (!providerPromise) { fireEvent({ action: _analytics.ACTION.ERRORED, actionSubject: _analytics.ACTION_SUBJECT.MENTION, actionSubjectId: _analytics.ACTION_SUBJECT_ID.MENTION_PROVIDER, eventType: _analytics.EVENT_TYPE.OPERATIONAL, attributes: { reason: _types2.MENTION_PROVIDER_UNDEFINED } }); return setProvider(undefined)(editorView.state, editorView.dispatch); } providerPromise.then(function (provider) { if (mentionProvider) { mentionProvider.unsubscribe('mentionPlugin'); } mentionProvider = provider; setProvider(provider)(editorView.state, editorView.dispatch); provider.subscribe('mentionPlugin', undefined, undefined, undefined, undefined, sendAnalytics); }).catch(function () { fireEvent({ action: _analytics.ACTION.ERRORED, actionSubject: _analytics.ACTION_SUBJECT.MENTION, actionSubjectId: _analytics.ACTION_SUBJECT_ID.MENTION_PROVIDER, eventType: _analytics.EVENT_TYPE.OPERATIONAL, attributes: { reason: _types2.MENTION_PROVIDER_REJECTED } }); return setProvider(undefined)(editorView.state, editorView.dispatch); }); break; } return; }; var providerViaConfig = (0, _fg.fg)('platform_editor_mention_provider_via_plugin_config'); if (providerViaConfig && options !== null && options !== void 0 && options.mentionProvider) { providerHandler('mentionProvider', options === null || options === void 0 ? void 0 : options.mentionProvider); } else { pmPluginFactoryParams.providerFactory.subscribe('mentionProvider', providerHandler); } return { destroy: function destroy() { if (pmPluginFactoryParams.providerFactory) { pmPluginFactoryParams.providerFactory.unsubscribe('mentionProvider', providerHandler); } if (mentionProvider) { mentionProvider.unsubscribe('mentionPlugin'); } } }; } }); }