@augment-vir/web
Version:
A collection of augments, helpers types, functions, and classes only for web (frontend) JavaScript environments.
81 lines (80 loc) • 3.25 kB
JavaScript
/**
* Gets all deeply nested elements contained within the given element, flattened into a single
* array. Shadow DOMs are traversed.
*
* Note that `<slot>` elements are included, as well as their nested elements (even if a slot filler
* is provided by the parent) and the slot filler itself (if provided).
*
* Optionally define a second "depth" input to control how far nestings should be pursued. Omit
* depth or set it to `undefined` or `0` to allow full depth search.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getNestedChildren(startingElement, depth) {
return recursivelyGetNestedChildren(startingElement, depth ?? 0, 0);
}
function recursivelyGetNestedChildren(startingElement, maxDepth, currentDepth) {
const children = getDirectChildren(startingElement);
return children.flatMap((child) => {
const nextDepth = currentDepth + 1;
const nested = maxDepth && nextDepth >= maxDepth
? []
: recursivelyGetNestedChildren(child, maxDepth, nextDepth);
return [
child,
nested,
].flat();
});
}
/**
* Gets all deeply nested elements contained within the given element in a tree. Shadow DOMs are
* traversed.
*
* Note that `<slot>` elements are included, as well as their nested elements (even if a slot filler
* is provided by the parent) and the slot filler itself (if provided).
*
* Optionally define a second "depth" input to control how far nestings should be pursued. Omit
* depth or set it to `undefined` or `0` to allow full depth search.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getNestedChildrenTree(startingElement, depth) {
return {
element: startingElement,
children: recursivelyGetNestedChildrenTree(startingElement, depth ?? 0, 0),
};
}
function recursivelyGetNestedChildrenTree(startingElement, maxDepth, currentDepth) {
return getDirectChildren(startingElement).map((child) => {
const nextDepth = currentDepth + 1;
const nested = maxDepth && nextDepth >= Math.abs(maxDepth)
? []
: recursivelyGetNestedChildrenTree(child, maxDepth, nextDepth);
return {
element: child,
children: nested,
};
});
}
/**
* Gets an element's direct children. Includes slotted elements, direct `<slot>` children
* themselves, and all direct children of a shadow DOM. Default `<slot>` children are not included
* (since they're not "direct" children as they are nested under `<slot>`).
*
* Note that that slotted elements and light dom elements will always be shown above shadow dom
* elements. Besides that, the order of children is preserved.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getDirectChildren(startingElement) {
return [
...startingElement.children,
...(startingElement.shadowRoot?.children ?? []),
];
}