@atlaskit/editor-common
Version:
A package that contains common classes and components for editor and renderer
72 lines (71 loc) • 1.94 kB
JavaScript
/**
* Type-specific predicates that vary between regular lists and task lists.
*/
/**
* Flattens a list-like PM structure (regular list or task list) into an
* array of content-bearing items with computed depths.
*
* Uses `doc.nodesBetween` to walk the tree and delegates type-specific
* decisions to the provided predicates. The core algorithm — selection
* intersection, depth adjustment, index tracking — is shared.
*/
export function flattenList(options, predicates) {
const {
doc,
rootListStart,
rootListEnd,
selectionFrom,
selectionTo,
indentDelta,
maxDepth
} = options;
const {
isContentNode,
getSelectionBounds,
getDepth
} = predicates;
const items = [];
let startIndex = -1;
let endIndex = -1;
let exceedsMaxDepth = false;
const rootDepth = doc.resolve(rootListStart).depth;
doc.nodesBetween(rootListStart, rootListEnd, (node, pos, parent) => {
if (!isContentNode(node, parent) || parent == null) {
return true;
}
const {
start,
end
} = getSelectionBounds(node, pos);
const isSelected = selectionFrom === selectionTo ? selectionFrom >= start && selectionFrom <= end : start < selectionTo && end > selectionFrom;
const resolvedDepth = doc.resolve(pos).depth;
const depth = getDepth(resolvedDepth, rootDepth) + (isSelected ? indentDelta : 0);
items.push({
node,
pos,
depth,
isSelected,
listType: parent.type.name,
parentListAttrs: parent.attrs
});
if (isSelected) {
const index = items.length - 1;
if (startIndex === -1) {
startIndex = index;
}
endIndex = index;
if (maxDepth != null && depth >= maxDepth) {
exceedsMaxDepth = true;
}
}
return true;
});
if (items.length === 0 || startIndex === -1 || exceedsMaxDepth) {
return null;
}
return {
items,
startIndex,
endIndex
};
}