(start: Node, finish: Node)
| 295 | * and `.nextSibling` operations. |
| 296 | */ |
| 297 | export function navigateBetween(start: Node, finish: Node): NodeNavigationStep[] | null { |
| 298 | if (start === finish) { |
| 299 | return []; |
| 300 | } else if (start.parentElement == null || finish.parentElement == null) { |
| 301 | return null; |
| 302 | } else if (start.parentElement === finish.parentElement) { |
| 303 | return navigateBetweenSiblings(start, finish); |
| 304 | } else { |
| 305 | // `finish` is a child of its parent, so the parent will always have a child. |
| 306 | const parent = finish.parentElement!; |
| 307 | |
| 308 | const parentPath = navigateBetween(start, parent); |
| 309 | const childPath = navigateBetween(parent.firstChild!, finish); |
| 310 | if (!parentPath || !childPath) return null; |
| 311 | |
| 312 | return [ |
| 313 | // First navigate to `finish`'s parent |
| 314 | ...parentPath, |
| 315 | // Then to its first child. |
| 316 | NODE_NAVIGATION_STEP_FIRST_CHILD, |
| 317 | // And finally from that node to `finish` (maybe a no-op if we're already there). |
| 318 | ...childPath, |
| 319 | ]; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | /** |
| 324 | * Calculates a path between 2 sibling nodes (generates a number of `NextSibling` navigations). |
no test coverage detected