UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

393 lines (391 loc) 21.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof3 = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.cardPlugin = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _messages = require("@atlaskit/editor-common/messages"); var _quickInsert = require("@atlaskit/editor-common/quick-insert"); var _utils = require("@atlaskit/editor-common/utils"); var _linkDatasource = require("@atlaskit/link-datasource"); var _context3 = require("@atlaskit/link-provider/context"); var _platformFeatureFlags = require("@atlaskit/platform-feature-flags"); var _expVal = require("@atlaskit/tmp-editor-statsig/expVal"); var _blockCard = require("./nodeviews/toDOM-fixes/blockCard"); var _embedCard = require("./nodeviews/toDOM-fixes/embedCard"); var _inlineCard = require("./nodeviews/toDOM-fixes/inlineCard"); var _actions = require("./pm-plugins/actions"); var _doc = require("./pm-plugins/doc"); var _keymap = require("./pm-plugins/keymap"); var _main = require("./pm-plugins/main"); var _pluginKey = require("./pm-plugins/plugin-key"); var _utils2 = require("./pm-plugins/utils"); var _createEventsQueue = require("./ui/analytics/create-events-queue"); var _ModalWithState = _interopRequireDefault(require("./ui/DatasourceModal/ModalWithState")); var _EditorLinkingPlatformAnalytics = require("./ui/EditorLinkingPlatformAnalytics"); var _EditorSmartCardEvents = require("./ui/EditorSmartCardEvents"); var _LayoutButton = _interopRequireDefault(require("./ui/LayoutButton")); var _PasteDisplayAsMenu = require("./ui/PasteDisplayAsMenu"); var _toolbar = require("./ui/toolbar"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t2 in e) "default" !== _t2 && {}.hasOwnProperty.call(e, _t2) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t2)) && (i.get || i.set) ? o(f, _t2, i) : f[_t2] = e[_t2]); return f; })(e, t); } 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; } // Ignored via go/ees005 // eslint-disable-next-line import/no-named-as-default var PasteMenuSmartCardClientSync = function PasteMenuSmartCardClientSync(_ref) { var _smartCardContext$con2; var clientRef = _ref.clientRef; var smartCardContext = (0, _react.useContext)(_context3.SmartCardContext); (0, _react.useEffect)(function () { var _smartCardContext$con; clientRef.current = smartCardContext === null || smartCardContext === void 0 || (_smartCardContext$con = smartCardContext.connections) === null || _smartCardContext$con === void 0 ? void 0 : _smartCardContext$con.client; }, [clientRef, smartCardContext === null || smartCardContext === void 0 || (_smartCardContext$con2 = smartCardContext.connections) === null || _smartCardContext$con2 === void 0 ? void 0 : _smartCardContext$con2.client]); return null; }; var cardPlugin = exports.cardPlugin = function cardPlugin(_ref2) { var _api$base, _options$lpLinkPicker; var _ref2$config = _ref2.config, options = _ref2$config === void 0 ? {} : _ref2$config, api = _ref2.api; var previousCardProvider; var cardPluginEvents = (0, _createEventsQueue.createEventsQueue)(); var instanceEmbedCardTransformers = options.embedCardTransformers; var editorViewForPasteMenu; var pasteMenuSmartCardClientRef = { current: undefined }; var pasteMenuVariant = (0, _expVal.expValNoExposure)('platform_editor_paste_actions_menu_v2', 'variant', 'control'); var shouldRegisterPasteDisplayAsMenu = options.enablePasteDisplayAsMenu && ['hasSpellingAndGrammar', 'hasAltAiActions'].includes(pasteMenuVariant); if (shouldRegisterPasteDisplayAsMenu) { var _api$uiControlRegistr, _options$allowBlockCa; api === null || api === void 0 || (_api$uiControlRegistr = api.uiControlRegistry) === null || _api$uiControlRegistr === void 0 || _api$uiControlRegistr.actions.register((0, _PasteDisplayAsMenu.getPasteDisplayAsMenuComponents)({ api: api, allowBlockCards: options.onlyInlineCards ? false : (_options$allowBlockCa = options.allowBlockCards) !== null && _options$allowBlockCa !== void 0 ? _options$allowBlockCa : true, allowEmbeds: options.onlyInlineCards ? false : options.allowEmbeds, getEditorView: function getEditorView() { return editorViewForPasteMenu; }, smartCardClientRef: pasteMenuSmartCardClientRef })); } api === null || api === void 0 || (_api$base = api.base) === null || _api$base === void 0 || _api$base.actions.registerMarks(function (_ref3) { var tr = _ref3.tr, node = _ref3.node, pos = _ref3.pos; var doc = tr.doc; var schema = doc.type.schema; var inlineCardNodeType = schema.nodes.inlineCard; if (node.type === inlineCardNodeType) { var newText = node.attrs.url; var currentPos = tr.mapping.map(pos); tr.replaceWith(currentPos, currentPos + node.nodeSize, schema.text(newText, node.marks)); } }); return { name: 'card', getSharedState: function getSharedState(editorState) { if (!editorState) { return null; } return _pluginKey.pluginKey.getState(editorState) || null; }, nodes: function nodes() { var nodes = [{ name: 'inlineCard', node: (0, _inlineCard.inlineCardSpecWithFixedToDOM)() }]; // `onlyInlineCards` is a hard gate: when set, blockCard/embedCard // stay out of the schema regardless of allowBlockCards/allowEmbeds. if (options.onlyInlineCards) { return nodes; } nodes.push({ name: 'blockCard', node: (0, _blockCard.blockCardSpecWithFixedToDOM)() }); if (options.allowEmbeds) { nodes.push({ name: 'embedCard', node: (0, _embedCard.embedCardSpecWithFixedToDOM)() }); } return nodes; }, pmPlugins: function pmPlugins() { var _options$allowBlockCa2, _options$allowResizin, _options$useAlternati, _options$allowWrappin, _options$allowAlignme, _options$allowDatasou, _options$showUpgradeD; // onlyInlineCards forces block/embed off regardless of caller-passed flags, // keeping the schema gate (in nodes()) and the runtime gate in sync. var allowBlockCards = options.onlyInlineCards ? false : (_options$allowBlockCa2 = options.allowBlockCards) !== null && _options$allowBlockCa2 !== void 0 ? _options$allowBlockCa2 : true; var allowEmbeds = options.onlyInlineCards ? false : options.allowEmbeds; var allowResizing = (_options$allowResizin = options.allowResizing) !== null && _options$allowResizin !== void 0 ? _options$allowResizin : true; var useAlternativePreloader = (_options$useAlternati = options.useAlternativePreloader) !== null && _options$useAlternati !== void 0 ? _options$useAlternati : true; var allowWrapping = (_options$allowWrappin = options.allowWrapping) !== null && _options$allowWrappin !== void 0 ? _options$allowWrappin : true; var allowAlignment = (_options$allowAlignme = options.allowAlignment) !== null && _options$allowAlignme !== void 0 ? _options$allowAlignme : true; var allowDatasource = (_options$allowDatasou = options.allowDatasource) !== null && _options$allowDatasou !== void 0 ? _options$allowDatasou : false; var showUpgradeDiscoverability = (_options$showUpgradeD = options.showUpgradeDiscoverability) !== null && _options$showUpgradeD !== void 0 ? _options$showUpgradeD : true; var plugins = [{ name: 'card', plugin: (0, _main.createPlugin)(_objectSpread(_objectSpread({}, options), {}, { allowBlockCards: allowBlockCards, allowEmbeds: allowEmbeds, allowResizing: allowResizing, useAlternativePreloader: useAlternativePreloader, allowWrapping: allowWrapping, allowAlignment: allowAlignment, allowDatasource: allowDatasource, cardPluginEvents: cardPluginEvents, embedCardTransformers: instanceEmbedCardTransformers, showUpgradeDiscoverability: showUpgradeDiscoverability }), api) }]; plugins.push({ name: 'cardKeymap', plugin: function plugin(_ref4) { var featureFlags = _ref4.featureFlags; return (0, _keymap.cardKeymap)(featureFlags); } }); return plugins; }, contentComponent: function contentComponent(_ref5) { var editorView = _ref5.editorView, popupsMountPoint = _ref5.popupsMountPoint, popupsScrollableElement = _ref5.popupsScrollableElement, popupsBoundariesElement = _ref5.popupsBoundariesElement; if (!editorView) { return null; } editorViewForPasteMenu = editorView; var breakoutEnabled = options.editorAppearance === 'full-page'; return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, shouldRegisterPasteDisplayAsMenu && /*#__PURE__*/_react.default.createElement(PasteMenuSmartCardClientSync, { clientRef: pasteMenuSmartCardClientRef }), /*#__PURE__*/_react.default.createElement(_EditorSmartCardEvents.EditorSmartCardEvents, { editorView: editorView }), /*#__PURE__*/_react.default.createElement(_EditorLinkingPlatformAnalytics.EditorLinkingPlatformAnalytics, { cardPluginEvents: cardPluginEvents, editorView: editorView }), breakoutEnabled && /*#__PURE__*/_react.default.createElement(_LayoutButton.default, { api: api, editorView: editorView, mountPoint: popupsMountPoint, scrollableElement: popupsScrollableElement, boundariesElement: popupsBoundariesElement }), /*#__PURE__*/_react.default.createElement(_ModalWithState.default, { api: api, editorView: editorView })); }, commands: { queueCardsFromRange: function queueCardsFromRange(from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance) { return function (_ref6) { var tr = _ref6.tr; return (0, _doc.queueCardsFromRange)( // Synthesise the minimal EditorState shape the impl actually reads. { schema: tr.doc.type.schema, selection: tr.selection }, tr, from, to, source, analyticsAction, normalizeLinkText, sourceEvent, appearance); }; } }, actions: { setProvider: function () { var _setProvider2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(providerPromise) { var _api$core$actions$exe; var provider; return _regenerator.default.wrap(function (_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.next = 1; return providerPromise; case 1: provider = _context.sent; if (!(previousCardProvider === provider || (options === null || options === void 0 ? void 0 : options.provider) === providerPromise)) { _context.next = 2; break; } return _context.abrupt("return", false); case 2: previousCardProvider = 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 (0, _actions.setProvider)(provider)(tr); })) !== null && _api$core$actions$exe !== void 0 ? _api$core$actions$exe : false); case 3: case "end": return _context.stop(); } }, _callee); })); function setProvider(_x) { return _setProvider2.apply(this, arguments); } return setProvider; }(), hideLinkToolbar: _actions.hideLinkToolbar, queueCardsFromChangedTr: _doc.queueCardsFromChangedTr, queueCardsFromRange: _doc.queueCardsFromRange, registerEmbedCardTransformer: function registerEmbedCardTransformer(transformers) { instanceEmbedCardTransformers = transformers; }, resolveShortLinkUrl: function () { var _resolveShortLinkUrl = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(url) { var provider, clientHolder, client, response, data, urlField, _linkObj$Id, linkObj, id, _t; return _regenerator.default.wrap(function (_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (options.provider) { _context2.next = 1; break; } return _context2.abrupt("return", undefined); case 1: _context2.prev = 1; _context2.next = 2; return options.provider; case 2: provider = _context2.sent; // EditorCardProvider holds a CardClient instance internally. We access it // directly to call fetchData, which gives us the raw ORS JSON-LD response // including the canonical url field — something provider.resolve() does not // surface. This is intentionally a structural cast rather than a typed // dependency on EditorCardProvider's private API. clientHolder = provider; client = clientHolder.cardClient; if (client) { _context2.next = 3; break; } return _context2.abrupt("return", undefined); case 3: _context2.next = 4; return client.fetchData(url); case 4: response = _context2.sent; // ORS returns a JsonLd.Response whose data union includes BaseData, // BaseCollectionData, and BaseCollectionPage. We only care about the // `url` field which is present on BaseData (Primitives.Object). Cast // to a minimal shape rather than accessing through the full union type. data = response === null || response === void 0 ? void 0 : response.data; if (data) { _context2.next = 5; break; } return _context2.abrupt("return", undefined); case 5: urlField = data.url; // Property<string | Link> can be a string, a Link object, or an array. // Short-link responses always return a plain string URL. if (!(typeof urlField === 'string' && urlField !== url)) { _context2.next = 6; break; } return _context2.abrupt("return", urlField); case 6: if (!(urlField && (0, _typeof2.default)(urlField) === 'object' && !Array.isArray(urlField))) { _context2.next = 7; break; } linkObj = urlField; id = (_linkObj$Id = linkObj['@id']) !== null && _linkObj$Id !== void 0 ? _linkObj$Id : linkObj['href']; if (!(typeof id === 'string' && id !== url)) { _context2.next = 7; break; } return _context2.abrupt("return", id); case 7: _context2.next = 9; break; case 8: _context2.prev = 8; _t = _context2["catch"](1); case 9: return _context2.abrupt("return", undefined); case 10: case "end": return _context2.stop(); } }, _callee2, null, [[1, 8]]); })); function resolveShortLinkUrl(_x2) { return _resolveShortLinkUrl.apply(this, arguments); } return resolveShortLinkUrl; }(), getStartingToolbarItems: (0, _toolbar.getStartingToolbarItems)(options, api), getEndingToolbarItems: (0, _toolbar.getEndingToolbarItems)(options, api) }, pluginsOptions: { floatingToolbar: (0, _toolbar.floatingToolbar)(options, (_options$lpLinkPicker = options.lpLinkPicker) !== null && _options$lpLinkPicker !== void 0 ? _options$lpLinkPicker : false, options.linkPicker, api, options.disableFloatingToolbar), quickInsert: function quickInsert(_ref8) { var formatMessage = _ref8.formatMessage; var quickInsertArray = []; if (!options.allowDatasource) { return quickInsertArray; } quickInsertArray.push(_objectSpread(_objectSpread({ id: 'datasource', title: formatMessage((0, _platformFeatureFlags.fg)('confluence-issue-terminology-refresh') ? _messages.cardMessages.datasourceJiraIssueIssueTermRefresh : _messages.cardMessages.datasourceJiraIssue), description: formatMessage((0, _platformFeatureFlags.fg)('confluence-issue-terminology-refresh') ? _messages.cardMessages.datasourceJiraIssueDescriptionIssueTermRefresh : _messages.cardMessages.datasourceJiraIssueDescription), isDisabledOffline: true, categories: ['external-content', 'development'], keywords: ['jira'], featured: true }, (0, _platformFeatureFlags.fg)('jim-lower-ranking-in-jira-macro-search') && { priority: 500 }), {}, { icon: function icon() { return /*#__PURE__*/_react.default.createElement(_quickInsert.IconDatasourceJiraIssue, null); }, action: function action(insert) { var tr = insert(undefined); (0, _actions.showDatasourceModal)('jira')(tr); return tr; } })); if ((0, _utils.canRenderDatasource)(_linkDatasource.ASSETS_LIST_OF_LINKS_DATASOURCE_ID)) { quickInsertArray.push({ id: 'datasource', title: formatMessage(_messages.cardMessages.datasourceAssetsObjectsGeneralAvailability), description: formatMessage(_messages.cardMessages.datasourceAssetsObjectsDescription), isDisabledOffline: true, categories: ['external-content', 'development'], keywords: ['assets'], icon: function icon() { return /*#__PURE__*/_react.default.createElement(_quickInsert.IconDatasourceAssetsObjects, null); }, action: function action(insert) { var tr = insert(undefined); (0, _actions.showDatasourceModal)('assets')(tr); return tr; } }); } if ((0, _utils2.isDatasourceConfigEditable)(_linkDatasource.CONFLUENCE_SEARCH_DATASOURCE_ID)) { quickInsertArray.push({ id: 'datasource', title: formatMessage(_messages.cardMessages.datasourceConfluenceSearch), description: formatMessage(_messages.cardMessages.datasourceConfluenceSearchDescription), isDisabledOffline: true, categories: ['external-content', 'development'], keywords: ['confluence'], featured: true, icon: function icon() { return /*#__PURE__*/_react.default.createElement(_quickInsert.IconDatasourceConfluenceSearch, null); }, action: function action(insert) { var tr = insert(undefined); (0, _actions.showDatasourceModal)('confluence-search')(tr); return tr; } }); } return quickInsertArray; } } }; };