* Return the lowest common ancestor of A and B, or null if they are in * different trees.
(instA, instB)
| 2532 | * different trees. |
| 2533 | */ |
| 2534 | function getLowestCommonAncestor(instA, instB) { |
| 2535 | var depthA = 0; |
| 2536 | for (var tempA = instA; tempA; tempA = getParent(tempA)) { |
| 2537 | depthA++; |
| 2538 | } |
| 2539 | var depthB = 0; |
| 2540 | for (var tempB = instB; tempB; tempB = getParent(tempB)) { |
| 2541 | depthB++; |
| 2542 | } |
| 2543 | |
| 2544 | // If A is deeper, crawl up. |
| 2545 | while (depthA - depthB > 0) { |
| 2546 | instA = getParent(instA); |
| 2547 | depthA--; |
| 2548 | } |
| 2549 | |
| 2550 | // If B is deeper, crawl up. |
| 2551 | while (depthB - depthA > 0) { |
| 2552 | instB = getParent(instB); |
| 2553 | depthB--; |
| 2554 | } |
| 2555 | |
| 2556 | // Walk in lockstep until we find a match. |
| 2557 | var depth = depthA; |
| 2558 | while (depth--) { |
| 2559 | if (instA === instB || instA === instB.alternate) { |
| 2560 | return instA; |
| 2561 | } |
| 2562 | instA = getParent(instA); |
| 2563 | instB = getParent(instB); |
| 2564 | } |
| 2565 | return null; |
| 2566 | } |
| 2567 | |
| 2568 | /** |
| 2569 | * Return if A is an ancestor of B. |
no test coverage detected