UNPKG

@atlaskit/editor-plugin-paste-options-toolbar

Version:

Paste options toolbar for @atlaskit/editor-core

70 lines (66 loc) 2.51 kB
/** * Structural container nodes are nodes whose children are determined by * document structure (e.g. list items inside a list, rows inside a table) * rather than by content choice. Having different child types inside these * nodes does NOT indicate mixed content. * * All other container nodes (blockTaskItem, blockquote, panel, * expand, layoutColumn, tableCell, tableHeader, bodiedExtension, etc.) hold * rich block content, so mixed block children inside them IS mixing. */ var STRUCTURAL_CONTAINERS = new Set(['bulletList', 'orderedList', 'listItem', 'taskList', 'decisionList', 'table', 'tableRow']); /** * Returns true if a node's direct block-level children include more than one * distinct node type — i.e. the children are "mixed". */ var hasBlockSiblings = function hasBlockSiblings(node) { var types = new Set(); node.forEach(function (child) { if (child.isBlock) { types.add(child.type.name); } }); return types.size > 1; }; /** * Returns true if the slice contains sibling block nodes of different types * at the same level anywhere in the document tree. * * Structural container nodes (bulletList, orderedList, taskList, decisionList, * table, tableRow) are excluded from the sibling check because their children * are typed by structure, not content. All other container nodes are checked. */ export var hasMixedNodes = function hasMixedNodes(slice) { var _slice$content; if (!(slice !== null && slice !== void 0 && (_slice$content = slice.content) !== null && _slice$content !== void 0 && _slice$content.size)) { return false; } // Check the top-level children of the slice (Fragment has no parent Node, // so we construct a synthetic check by iterating slice.content directly). var topLevelTypes = new Set(); slice.content.forEach(function (node) { if (node.isBlock) { topLevelTypes.add(node.type.name); } }); if (topLevelTypes.size > 1) { return true; } // Walk every descendant node and check its direct block children for mixing, // skipping structural containers (their children are structural, not content). var mixed = false; slice.content.descendants(function (node) { if (mixed) { return false; // short-circuit once found } if (STRUCTURAL_CONTAINERS.has(node.type.name)) { return true; // recurse into but don't check children for mixing } if (hasBlockSiblings(node)) { mixed = true; return false; } return true; }); return mixed; };