42 lines
1.2 KiB
TypeScript
42 lines
1.2 KiB
TypeScript
|
// Copyright: Ankitects Pty Ltd and contributors
|
||
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||
|
|
||
|
function getNodeCoordinatesRecursive(
|
||
|
node: Node,
|
||
|
base: Node,
|
||
|
coordinates: number[],
|
||
|
): number[] {
|
||
|
/* parentNode: Element | Document | DocumentFragment */
|
||
|
if (!node.parentNode || node === base) {
|
||
|
return coordinates;
|
||
|
} else {
|
||
|
const parent = node.parentNode;
|
||
|
const newCoordinates = [
|
||
|
Array.prototype.indexOf.call(node.parentNode.childNodes, node),
|
||
|
...coordinates,
|
||
|
];
|
||
|
return getNodeCoordinatesRecursive(parent, base, newCoordinates);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export function getNodeCoordinates(node: Node, base: Node): number[] {
|
||
|
return getNodeCoordinatesRecursive(node, base, []);
|
||
|
}
|
||
|
|
||
|
export function findNodeFromCoordinates(
|
||
|
base: Node,
|
||
|
coordinates: number[],
|
||
|
): Node | null {
|
||
|
if (coordinates.length === 0) {
|
||
|
return base;
|
||
|
} else if (!base.childNodes[coordinates[0]]) {
|
||
|
return null;
|
||
|
} else {
|
||
|
const [firstCoordinate, ...restCoordinates] = coordinates;
|
||
|
return findNodeFromCoordinates(
|
||
|
base.childNodes[firstCoordinate],
|
||
|
restCoordinates,
|
||
|
);
|
||
|
}
|
||
|
}
|