UNPKG

@atlaskit/adf-utils

Version:

Set of utilities to traverse, modify and create ADF documents.

68 lines (67 loc) 2.45 kB
import { traverse } from '../traverse/traverse'; import { isEmpty } from './helpers'; const getChildrenTypeCounts = (nodeContent, allowedTypes) => { const childrenTypes = {}; nodeContent.forEach(childNode => { if (!(childNode !== null && childNode !== void 0 && childNode.type) || !allowedTypes.includes(childNode.type)) { return; } if (!childrenTypes[childNode.type]) { childrenTypes[childNode.type] = 1; return; } childrenTypes[childNode.type]++; }); return childrenTypes; }; const removeDuplicatedNodes = (type, content, predicate) => { let maxIterations = 10; let childrenTypeCounts = getChildrenTypeCounts(content, [type])[type]; let firstPredicateNodeIndex = content.findIndex(predicate); while (childrenTypeCounts > 1 && firstPredicateNodeIndex > -1 && maxIterations-- > 0) { content.splice(firstPredicateNodeIndex, 1); firstPredicateNodeIndex = content.findIndex(predicate); childrenTypeCounts = getChildrenTypeCounts(content, [type])[type]; } }; /** * @param {{[type:string]:number}} allowedTypes - array types allowed to deduplicate */ const deduplicateMediaSingleChildren = (node, allowedTypes) => { if (!node.content) { return; } const content = [...node.content]; Object.keys(allowedTypes).forEach(type => { //prioritise removing empty nodes first removeDuplicatedNodes(type, content, node => (node === null || node === void 0 ? void 0 : node.type) === type && isEmpty(node)); //remove other remaining dupicates removeDuplicatedNodes(type, content, node => (node === null || node === void 0 ? void 0 : node.type) === type); }); return { ...node, content }; }; export const transformInvalidMediaContent = adf => { let isTransformed = false; const transformedAdf = traverse(adf, { mediaSingle: node => { var _node$content; if (!(node !== null && node !== void 0 && (_node$content = node.content) !== null && _node$content !== void 0 && _node$content.length)) { return; } const disallowedDuplicateTypes = ['media', 'caption']; const childrenTypes = getChildrenTypeCounts(node.content, disallowedDuplicateTypes); if (Object.values(childrenTypes).some(occurences => occurences > 1)) { isTransformed = true; return deduplicateMediaSingleChildren(node, childrenTypes); } return; } }); return { transformedAdf, isTransformed }; };