UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

84 lines (81 loc) 3.69 kB
import { canRenderDatasource, hasDocAsParent } from '@atlaskit/editor-common/utils'; import { setProvider } from '../actions'; import { handleFallbackWithAnalytics, replaceQueuedUrlWithCard } from '../doc'; const isFreshlyPastedOnNewLine = view => { const { selection } = view.state; const { $cursor, $anchor } = selection; if (!$cursor) { return false; } if (!hasDocAsParent($anchor)) { return false; } const node = $cursor.node(); if (!node) { return false; } if (node.type.name !== 'paragraph') { return false; } return node.childCount === 1; // The pasted blue link itself }; // ============================================================================ // // ============================== PROVIDER UTILS ============================== // // ============================================================================ // // Used for all interactions with the EditorCardProvider. // ============================================================================ // export const resolveWithProvider = (view, provider, request, options, editorAnalyticsApi, createAnalyticsEvent, embedCardNodeTransformer) => { const isEmbedFriendlyLocation = isFreshlyPastedOnNewLine(view); // When user manually changes appearance from blue link to smart link, we should respect that, const shouldForceAppearance = // This flag is set to true only in one place atm: // packages/editor/editor-core/src/plugins/card/pm-plugins/doc.ts @ convertHyperlinkToSmartCard // Which is used when user switching from URL to smart link appearance. !!request.shouldReplaceLink; const handleResolve = provider.resolve(request.url, request.appearance, shouldForceAppearance, isEmbedFriendlyLocation).then(handleResolved(view, request, editorAnalyticsApi, createAnalyticsEvent, options, embedCardNodeTransformer), handleRejected(view, request, editorAnalyticsApi)); return handleResolve; }; const updateCardType = (resolvedCard, options) => { if (resolvedCard.type === 'blockCard' && 'datasource' in resolvedCard.attrs) { const datasourceId = resolvedCard.attrs.datasource.id; if (!options.allowDatasource || !canRenderDatasource(datasourceId)) { delete resolvedCard.attrs.datasource; resolvedCard.type = 'inlineCard'; return; } } if ((resolvedCard === null || resolvedCard === void 0 ? void 0 : resolvedCard.type) === 'blockCard' && !options.allowBlockCards || (resolvedCard === null || resolvedCard === void 0 ? void 0 : resolvedCard.type) === 'embedCard' && !options.allowEmbeds) { // clean out the 'layout' attr from an embedCard type that should be transformed into the inlineCard type. if (resolvedCard.type === 'embedCard') { // eslint-disable-next-line @typescript-eslint/no-explicit-any delete resolvedCard.attrs.layout; } resolvedCard.type = 'inlineCard'; } }; const handleResolved = (view, request, editorAnalyticsApi, createAnalyticsEvent, options, embedCardNodeTransformer) => resolvedCard => { updateCardType(resolvedCard, options); replaceQueuedUrlWithCard(request.url, resolvedCard, request.analyticsAction, editorAnalyticsApi, createAnalyticsEvent, embedCardNodeTransformer)(view.state, view.dispatch); return resolvedCard; }; const handleRejected = (view, request, editorAnalyticsApi) => () => { handleFallbackWithAnalytics(request, editorAnalyticsApi)(view.state, view.dispatch); }; // listen for card provider changes export const handleProvider = (_, provider, view) => { if (!provider) { return; } provider.then(cardProvider => { const { state, dispatch } = view; dispatch(setProvider(cardProvider)(state.tr)); }); };