UNPKG

@atlaskit/editor-plugin-mentions

Version:

Mentions plugin for @atlaskit/editor-core

243 lines 11.8 kB
import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _regeneratorRuntime from "@babel/runtime/regenerator"; 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 { getBrowserInfo } from '@atlaskit/editor-common/browser'; import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace'; import { DOMSerializer } from '@atlaskit/editor-prosemirror/model'; import { isResolvingMentionProvider, MentionNameStatus } from '@atlaskit/mention/resource'; import { isRestricted } from '@atlaskit/mention/types'; import { fg } from '@atlaskit/platform-feature-flags'; import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals'; import { profileCardRenderer } from './profileCardRenderer'; var primitiveClassName = 'editor-mention-primitive'; // @ts-ignore - TS1501 TypeScript 5.9.2 upgrade var getAccessibilityLabelFromName = function getAccessibilityLabelFromName(name) { return name.replace(/^@/, ''); }; var toDOM = function toDOM(node) { // packages/elements/mention/src/components/Mention/index.tsx var mentionAttrs = { contenteditable: 'false', 'data-access-level': node.attrs.accessLevel, 'data-mention-id': node.attrs.id, 'data-prosemirror-content-type': 'node', 'data-prosemirror-node-inline': 'true', 'data-prosemirror-node-name': 'mention', 'data-prosemirror-node-view-type': 'vanilla', class: 'mentionView-content-wrap inlineNodeView' }; if (fg('platform_editor_adf_with_localid')) { mentionAttrs = _objectSpread(_objectSpread({}, mentionAttrs), {}, { 'data-local-id': node.attrs.localId }); } var browser = getBrowserInfo(); return ['span', mentionAttrs, ['span', { class: 'zeroWidthSpaceContainer' }, ['span', { class: 'inlineNodeViewAddZeroWidthSpace' }, ZERO_WIDTH_SPACE]], ['span', { spellcheck: 'false', class: primitiveClassName }, node.attrs.text || '@…'], browser.android ? ['span', { class: 'zeroWidthSpaceContainer', contenteditable: 'false' }, ['span', { class: 'inlineNodeViewAddZeroWidthSpace' }, ZERO_WIDTH_SPACE]] : ['span', { class: 'inlineNodeViewAddZeroWidthSpace' }, ZERO_WIDTH_SPACE]]; }; var processName = function processName(name) { return name.status === MentionNameStatus.OK ? "@".concat(name.name || '') : "@_|unknown|_"; }; var handleProviderName = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(mentionProvider, node) { var nameDetail, resolvedNameDetail; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (!(isResolvingMentionProvider(mentionProvider) && node.attrs.id && !node.attrs.text)) { _context.next = 6; break; } nameDetail = mentionProvider === null || mentionProvider === void 0 ? void 0 : mentionProvider.resolveMentionName(node.attrs.id); _context.next = 4; return nameDetail; case 4: resolvedNameDetail = _context.sent; return _context.abrupt("return", processName(resolvedNameDetail)); case 6: case "end": return _context.stop(); } }, _callee); })); return function handleProviderName(_x, _x2) { return _ref.apply(this, arguments); }; }(); var getNewState = function getNewState(isHighlighted, isRestricted) { if (isHighlighted) { return 'self'; } if (isRestricted) { return 'restricted'; } return 'default'; }; export var MentionNodeView = /*#__PURE__*/function () { function MentionNodeView(node, config) { var _this$domElement$quer, _api$mention$sharedSt, _this = this; _classCallCheck(this, MentionNodeView); _defineProperty(this, "state", 'default'); var options = config.options, api = config.api, portalProviderAPI = config.portalProviderAPI; var _DOMSerializer$render = DOMSerializer.renderSpec(document, toDOM(node)), dom = _DOMSerializer$render.dom, contentDOM = _DOMSerializer$render.contentDOM; this.dom = dom; this.contentDOM = contentDOM; this.config = config; this.node = node; this.domElement = dom instanceof HTMLElement ? dom : undefined; this.mentionPrimitiveElement = this.domElement ? (_this$domElement$quer = this.domElement.querySelector(".".concat(primitiveClassName))) !== null && _this$domElement$quer !== void 0 ? _this$domElement$quer : undefined : undefined; var _ref2 = (_api$mention$sharedSt = api === null || api === void 0 ? void 0 : api.mention.sharedState.currentState()) !== null && _api$mention$sharedSt !== void 0 ? _api$mention$sharedSt : {}, mentionProvider = _ref2.mentionProvider; this.updateState(mentionProvider); this.cleanup = api === null || api === void 0 ? void 0 : api.mention.sharedState.onChange(function (_ref3) { var nextSharedState = _ref3.nextSharedState; _this.updateState(nextSharedState === null || nextSharedState === void 0 ? void 0 : nextSharedState.mentionProvider); }); var _profileCardRenderer = profileCardRenderer({ dom: dom, options: options, portalProviderAPI: portalProviderAPI, node: node, api: api }), destroyProfileCard = _profileCardRenderer.destroyProfileCard, removeProfileCard = _profileCardRenderer.removeProfileCard; // Accessibility attributes - based on `packages/people-and-teams/profilecard/src/components/User/ProfileCardTrigger.tsx` if (this.domElement && options !== null && options !== void 0 && options.profilecardProvider) { if (node.attrs.text) { this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(node.attrs.text)); } this.domElement.setAttribute('aria-expanded', 'false'); this.domElement.setAttribute('role', 'button'); this.domElement.setAttribute('tabindex', '0'); this.domElement.setAttribute('aria-haspopup', 'dialog'); } this.destroyProfileCard = destroyProfileCard; this.removeProfileCard = removeProfileCard; } return _createClass(MentionNodeView, [{ key: "setClassList", value: function setClassList(state) { var _this$mentionPrimitiv, _this$mentionPrimitiv2; (_this$mentionPrimitiv = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv === void 0 || _this$mentionPrimitiv.classList.toggle('mention-self', state === 'self'); (_this$mentionPrimitiv2 = this.mentionPrimitiveElement) === null || _this$mentionPrimitiv2 === void 0 || _this$mentionPrimitiv2.classList.toggle('mention-restricted', state === 'restricted'); } }, { key: "setTextContent", value: function setTextContent(name) { if (name && !this.node.attrs.text && this.mentionPrimitiveElement) { this.mentionPrimitiveElement.textContent = name; } } }, { key: "shouldHighlightMention", value: function shouldHighlightMention(mentionProvider) { var _this$config$options; var _ref4 = (_this$config$options = this.config.options) !== null && _this$config$options !== void 0 ? _this$config$options : {}, currentUserId = _ref4.currentUserId; // Check options first (immediate), then provider (async), then default to false if (currentUserId && this.node.attrs.id === currentUserId) { return true; } else { var _mentionProvider$shou; return (_mentionProvider$shou = mentionProvider === null || mentionProvider === void 0 ? void 0 : mentionProvider.shouldHighlightMention({ id: this.node.attrs.id })) !== null && _mentionProvider$shou !== void 0 ? _mentionProvider$shou : false; } } }, { key: "updateState", value: function () { var _updateState = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(mentionProvider) { var _mentionProvider$shou2, _this$config$options2; var isHighlighted, newState, name; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: isHighlighted = expValEquals('platform_editor_vc90_transition_mentions', 'isEnabled', true) ? this.shouldHighlightMention(mentionProvider) : (_mentionProvider$shou2 = mentionProvider === null || mentionProvider === void 0 ? void 0 : mentionProvider.shouldHighlightMention({ id: this.node.attrs.id })) !== null && _mentionProvider$shou2 !== void 0 ? _mentionProvider$shou2 : false; newState = getNewState(isHighlighted, isRestricted(this.node.attrs.accessLevel)); if (newState !== this.state) { this.setClassList(newState); this.state = newState; } _context2.next = 5; return handleProviderName(mentionProvider, this.node); case 5: name = _context2.sent; this.setTextContent(name); if (name && this.domElement && (_this$config$options2 = this.config.options) !== null && _this$config$options2 !== void 0 && _this$config$options2.profilecardProvider) { this.domElement.setAttribute('aria-label', getAccessibilityLabelFromName(name)); } case 8: case "end": return _context2.stop(); } }, _callee2, this); })); function updateState(_x3) { return _updateState.apply(this, arguments); } return updateState; }() }, { key: "nodeIsEqual", value: function nodeIsEqual(nextNode) { var _this$config$options3; if ((_this$config$options3 = this.config.options) !== null && _this$config$options3 !== void 0 && _this$config$options3.sanitizePrivateContent) { // Compare nodes but ignore the text parameter as it may be sanitized var nextNodeAttrs = _objectSpread(_objectSpread({}, nextNode.attrs), {}, { text: this.node.attrs.text }); return this.node.hasMarkup(nextNode.type, nextNodeAttrs, nextNode.marks); } return this.node.sameMarkup(nextNode); } }, { key: "update", value: function update(node) { if (!this.nodeIsEqual(node)) { return false; } this.node = node; return true; } }, { key: "destroy", value: function destroy() { var _this$cleanup, _this$destroyProfileC; (_this$cleanup = this.cleanup) === null || _this$cleanup === void 0 || _this$cleanup.call(this); (_this$destroyProfileC = this.destroyProfileCard) === null || _this$destroyProfileC === void 0 || _this$destroyProfileC.call(this); } }, { key: "deselectNode", value: function deselectNode() { var _this$removeProfileCa; (_this$removeProfileCa = this.removeProfileCard) === null || _this$removeProfileCa === void 0 || _this$removeProfileCa.call(this); } }]); }();