@atlaskit/adf-utils
Version:
Set of utilities to traverse, modify and create ADF documents.
68 lines (67 loc) • 2.45 kB
JavaScript
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
};
};