| 557 | ) => void; |
| 558 | |
| 559 | export function observeVisibleRects( |
| 560 | hostRoot: Instance, |
| 561 | selectors: Array<Selector>, |
| 562 | callback: (intersections: Array<{ratio: number, rect: BoundingRect}>) => void, |
| 563 | options?: IntersectionObserverOptions, |
| 564 | ): {disconnect: () => void} { |
| 565 | if (!supportsTestSelectors) { |
| 566 | throw new Error('Test selector API is not supported by this renderer.'); |
| 567 | } |
| 568 | |
| 569 | const instanceRoots = findAllNodes(hostRoot, selectors); |
| 570 | |
| 571 | const {disconnect, observe, unobserve} = setupIntersectionObserver( |
| 572 | instanceRoots, |
| 573 | callback, |
| 574 | options, |
| 575 | ); |
| 576 | |
| 577 | // When React mutates the host environment, we may need to change what we're listening to. |
| 578 | const commitHook = () => { |
| 579 | const nextInstanceRoots = findAllNodes(hostRoot, selectors); |
| 580 | |
| 581 | instanceRoots.forEach(target => { |
| 582 | if (nextInstanceRoots.indexOf(target) < 0) { |
| 583 | unobserve(target); |
| 584 | } |
| 585 | }); |
| 586 | |
| 587 | nextInstanceRoots.forEach(target => { |
| 588 | if (instanceRoots.indexOf(target) < 0) { |
| 589 | observe(target); |
| 590 | } |
| 591 | }); |
| 592 | }; |
| 593 | |
| 594 | commitHooks.push(commitHook); |
| 595 | |
| 596 | return { |
| 597 | disconnect: () => { |
| 598 | // Stop listening for React mutations: |
| 599 | const index = commitHooks.indexOf(commitHook); |
| 600 | if (index >= 0) { |
| 601 | commitHooks.splice(index, 1); |
| 602 | } |
| 603 | |
| 604 | // Disconnect the host observer: |
| 605 | disconnect(); |
| 606 | }, |
| 607 | }; |
| 608 | } |