UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

94 lines 3.18 kB
import { getNativeEmbedUrl, isNativeEmbedNode } from './nativeEmbedNode'; export const DISPLAY_AS_OPTIONS = ['url', 'inline', 'block', 'embed']; const cardAtPos = (node, pos) => { switch (node === null || node === void 0 ? void 0 : node.type.name) { case 'inlineCard': return { appearance: 'inline', pos }; case 'blockCard': return { appearance: 'block', pos }; case 'embedCard': return { appearance: 'embed', pos }; default: return isNativeEmbedNode(node) ? { appearance: 'embed', isNativeEmbed: true, pos } : undefined; } }; const getNodeUrl = node => { var _attrs$url, _attrs$data; if (isNativeEmbedNode(node)) { return getNativeEmbedUrl(node); } const attrs = node.attrs; const url = (_attrs$url = attrs === null || attrs === void 0 ? void 0 : attrs.url) !== null && _attrs$url !== void 0 ? _attrs$url : attrs === null || attrs === void 0 ? void 0 : (_attrs$data = attrs.data) === null || _attrs$data === void 0 ? void 0 : _attrs$data.url; return typeof url === 'string' ? url : undefined; }; /** * Finds the card that a paste produced. * * The paste range is recorded when the paste happens and then mapped through every later * transaction, so by the time the link has resolved into a card the range can point just * past that card. `pastedUrl` resolves the ambiguity: when it is known, a candidate * holding that URL wins over one that merely sits in the range, which stops a pre-existing * neighbouring card from being reported as the pasted one. */ export const getCardAtPasteRange = (state, pasteStartPos, pasteEndPos, pastedUrl) => { const docContentSize = state.doc.content.size; const clampedStart = Math.max(0, Math.min(pasteStartPos, docContentSize)); const clampedEnd = Math.max(0, Math.min(pasteEndPos, docContentSize)); const from = Math.min(clampedStart, clampedEnd); const to = Math.max(clampedStart, clampedEnd); try { var _inRange; const candidateAt = pos => { if (pos < 0 || pos >= docContentSize) { return undefined; } const node = state.doc.nodeAt(pos); const card = cardAtPos(node, pos); return node && card ? { card, url: getNodeUrl(node) } : undefined; }; const adjacent = [candidateAt(from - 1), candidateAt(from)].filter(candidate => Boolean(candidate)); const inRange = []; state.doc.nodesBetween(from, to, (node, pos) => { const card = cardAtPos(node, pos); if (card) { inRange.push({ card, url: getNodeUrl(node) }); return false; } return true; }); if (pastedUrl) { const match = [...adjacent, ...inRange].find(candidate => candidate.url === pastedUrl); if (match) { return match.card; } } if (from === to) { const [firstAdjacent] = adjacent; if (firstAdjacent) { return firstAdjacent.card; } } return (_inRange = inRange[inRange.length - 1]) === null || _inRange === void 0 ? void 0 : _inRange.card; } catch { return undefined; } };