@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
113 lines (111 loc) • 5.53 kB
JavaScript
import { traverse } from '@atlaskit/adf-utils/traverse';
export let UNSUPPORTED_CONTENT_LEVEL_SEVERITY = /*#__PURE__*/function (UNSUPPORTED_CONTENT_LEVEL_SEVERITY) {
UNSUPPORTED_CONTENT_LEVEL_SEVERITY["NORMAL"] = "normal";
UNSUPPORTED_CONTENT_LEVEL_SEVERITY["DEGRADED"] = "degraded";
UNSUPPORTED_CONTENT_LEVEL_SEVERITY["BLOCKING"] = "blocking";
return UNSUPPORTED_CONTENT_LEVEL_SEVERITY;
}({});
export const UNSUPPORTED_CONTENT_LEVEL_SEVERITY_THRESHOLD_DEFAULTS = {
DEGRADED: 10,
BLOCKING: 25
};
const buildUnsupportedContentLevelThresholds = customThresholds => {
return {
degraded: (customThresholds === null || customThresholds === void 0 ? void 0 : customThresholds.degraded) || UNSUPPORTED_CONTENT_LEVEL_SEVERITY_THRESHOLD_DEFAULTS.DEGRADED,
blocking: (customThresholds === null || customThresholds === void 0 ? void 0 : customThresholds.blocking) || UNSUPPORTED_CONTENT_LEVEL_SEVERITY_THRESHOLD_DEFAULTS.BLOCKING
};
};
const countSupportedUnsupportedNodes = validDocument => {
let unsupportedNodes = 0;
let supportedNodes = 0;
const unsupportedNodeTypeCount = {};
const unsupportedNodeTypes = ['unsupportedInline', 'unsupportedBlock', 'confluenceUnsupportedInline', 'confluenceUnsupportedBlock'];
traverse(validDocument, {
any: node => {
if (unsupportedNodeTypes.includes(node.type)) {
var _node$attrs;
const originalNode = (_node$attrs = node.attrs) === null || _node$attrs === void 0 ? void 0 : _node$attrs.originalValue;
if (originalNode) {
// start an independent traversal for the purpose of counting
// unsupported content nodes (with nested children contributing towards
// that count)
traverse(originalNode, {
any: (unsupportedNode, parent) => {
var _parent$parent$node$t, _parent$parent, _parent$parent$node, _unsupportedNode$type, _unsupportedNodeTypeC;
unsupportedNodes++;
// Count the types of unsupported nodes
const parentType = (_parent$parent$node$t = (_parent$parent = parent.parent) === null || _parent$parent === void 0 ? void 0 : (_parent$parent$node = _parent$parent.node) === null || _parent$parent$node === void 0 ? void 0 : _parent$parent$node.type) !== null && _parent$parent$node$t !== void 0 ? _parent$parent$node$t : 'unknown';
const type = `${parentType}/${(_unsupportedNode$type = unsupportedNode === null || unsupportedNode === void 0 ? void 0 : unsupportedNode.type) !== null && _unsupportedNode$type !== void 0 ? _unsupportedNode$type : 'unknown'}`;
unsupportedNodeTypeCount[type] = ((_unsupportedNodeTypeC = unsupportedNodeTypeCount === null || unsupportedNodeTypeCount === void 0 ? void 0 : unsupportedNodeTypeCount[type]) !== null && _unsupportedNodeTypeC !== void 0 ? _unsupportedNodeTypeC : 0) + 1;
}
});
}
// force the parent traversal (which is counting supported content nodes)
// to skip traversal/counting of nested children of the unsupported nodes
return false;
} else {
supportedNodes++;
}
}
});
return {
unsupportedNodes,
supportedNodes,
unsupportedNodeTypeCount
};
};
const mapUnsupportedContentLevelToSeverity = (unsupportedContentLevelPercent, thresholds) => {
if (thresholds.degraded <= unsupportedContentLevelPercent && unsupportedContentLevelPercent < thresholds.blocking) {
return UNSUPPORTED_CONTENT_LEVEL_SEVERITY.DEGRADED;
}
if (thresholds.blocking <= unsupportedContentLevelPercent) {
return UNSUPPORTED_CONTENT_LEVEL_SEVERITY.BLOCKING;
}
return UNSUPPORTED_CONTENT_LEVEL_SEVERITY.NORMAL;
};
/**
* When given a valid ADF document, this function will return an information
* object about the level of unsupported content in the document including:
*
* - counts: an object with the unsupportedNodes count and supportedNodes count.
* - percentage: the percentage of unsupported nodes in the document relative to the rest
* of the document content
* - severity: The percentage mapped to a string value. This string will be either
* "normal", "degraded" or "blocking" based on the threshold rules. (For e.g. if
* `customThresholds = { degraded: 10, blocking: 30 }`, then a document with 9%
* unsupported content will map to "normal", a document with 14% unsupported content
* will map to "degraded" and a document with 33% unsupported content will map to "blocking".)
*
* **Example usage**
*
* ```
* const exampleAdf = { type: 'doc', version: 1, content: [...] };
* const customThresholds = { degraded: 30, blocking: 50 };
* const data = getUnsupportedContentLevelData(exampleAdf, customThresholds);
*
* console.log(data.severity); // "normal"
* console.log(data.counts.percentage); // 28
* console.log(data.counts.unsupportedNodes); // 50
* console.log(data.counts.supportedNodes); // 129
* ```
*
*/
export const getUnsupportedContentLevelData = (validDocument, customThresholds) => {
const {
unsupportedNodes,
supportedNodes,
unsupportedNodeTypeCount
} = countSupportedUnsupportedNodes(validDocument);
const thresholds = buildUnsupportedContentLevelThresholds(customThresholds);
const percentage = Math.round(unsupportedNodes / (unsupportedNodes + supportedNodes) * 100);
const severity = mapUnsupportedContentLevelToSeverity(percentage, thresholds);
return {
severity,
percentage,
counts: {
supportedNodes,
unsupportedNodes,
unsupportedNodeTypeCount
}
};
};