UNPKG

@atlaskit/editor-plugin-card

Version:

Card plugin for @atlaskit/editor-core

118 lines (115 loc) 3.26 kB
import { appearanceForNodeType } from '../../pm-plugins/utils'; import { EVENT_SUBJECT } from './types'; export function isDatasourceNode(node) { return 'datasource' in node.attrs && !!node.attrs.datasource; } /** * Determine if a node is considered to be a link */ export const isLinkNode = node => { if (isDatasourceNode(node)) { return false; } if (!!appearanceForNodeType(node.type)) { return true; } return hasLinkMark(node); }; export function getNodeSubject(node) { if (isDatasourceNode(node)) { return EVENT_SUBJECT.DATASOURCE; } if (isLinkNode(node)) { return EVENT_SUBJECT.LINK; } return null; } /** * Analytics appearance for link object */ export function appearanceForLink(node) { const appearance = appearanceForNodeType(node.type); if (appearance) { return appearance; } return 'url'; } const getLinkMark = node => { if (node.marks) { for (let i = 0; i < node.marks.length; i++) { const mark = node.marks[i]; if (mark.type.name === 'link') { return mark; } } } }; const hasLinkMark = node => { return !!getLinkMark(node); }; export function getUrl(node) { var _node$attrs$url, _node$attrs, _getLinkMark, _getLinkMark$attrs; return (_node$attrs$url = (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.url) !== null && _node$attrs$url !== void 0 ? _node$attrs$url : (_getLinkMark = getLinkMark(node)) === null || _getLinkMark === void 0 ? void 0 : (_getLinkMark$attrs = _getLinkMark.attrs) === null || _getLinkMark$attrs === void 0 ? void 0 : _getLinkMark$attrs.href; } export const getNodeContext = (doc, pos) => { const $pos = doc.resolve(pos); const maxDepth = 3; for (let i = 0; i <= maxDepth; i++) { const node = $pos.node($pos.depth - i); if (node && node.type.name !== 'paragraph') { return node.type.name; } } return 'unknown'; }; export const findAtPositions = (tr, positions) => { const entities = []; for (let i = 0; i < positions.length; i++) { const pos = positions[i]; const node = tr.doc.nodeAt(pos); if (!node) { continue; } const nodeContext = getNodeContext(tr.doc, pos); entities.push({ pos, node, nodeContext }); } return entities; }; export const findInNodeRange = (doc, from, to, predicate) => { const entities = []; doc.nodesBetween(from, to, (node, pos) => { if (predicate(node)) { const entirelyInRange = pos >= from && pos + node.nodeSize <= to; if (entirelyInRange) { const nodeContext = getNodeContext(doc, pos); entities.push({ pos, node, nodeContext }); } } }); return entities; }; /** * Returns whether or not two sets of links appear to likely be the same set of links * That they are in the same order and that both their hrefs and appearances match */ export const areSameNodes = (setA, setB) => { if (setA.length !== setB.length) { return false; } for (let i = 0; i < setA.length; i++) { const a = setA[i]; const b = setB[i]; if (getUrl(a.node) !== getUrl(b.node) || appearanceForLink(a.node) !== appearanceForLink(b.node)) { return false; } } return true; };