44 * This source code is licensed under the MIT license found in the
55 * LICENSE file in the root directory of this source tree.
66 *
7- * @fantom_flags enableIntersectionObserverEventLoopIntegration:true
8- * @fantom_flags utilizeTokensInIntersectionObserver:true
7+ * @fantom_flags enableIntersectionObserverEventLoopIntegration:*
8+ * @fantom_flags utilizeTokensInIntersectionObserver:*
99 * @flow strict-local
1010 * @format
1111 */
@@ -21,6 +21,7 @@ import * as Fantom from '@react-native/fantom';
2121import * as React from 'react' ;
2222import { createRef , useState } from 'react' ;
2323import { ScrollView , View } from 'react-native' ;
24+ import * as ReactNativeFeatureFlags from 'react-native/src/private/featureflags/ReactNativeFeatureFlags' ;
2425import setUpIntersectionObserver from 'react-native/src/private/setup/setUpIntersectionObserver' ;
2526import ReactNativeElement from 'react-native/src/private/webapis/dom/nodes/ReactNativeElement' ;
2627import DOMRectReadOnly from 'react-native/src/private/webapis/geometry/DOMRectReadOnly' ;
@@ -846,91 +847,97 @@ describe('IntersectionObserver', () => {
846847 } ) ;
847848 } ) ;
848849
849- it ( 'should not retain initial children of observed targets' , ( ) => {
850- const root = Fantom . createRoot ( ) ;
851- observer = new IntersectionObserver ( ( ) => { } ) ;
852-
853- const [ getReferenceCount , ref ] = createShadowNodeReferenceCountingRef ( ) ;
854-
855- const observeRef : React . RefSetter <
856- React . ElementRef < typeof View > ,
857- > = instance => {
858- const element = ensureReactNativeElement ( instance ) ;
859- observer . observe ( element ) ;
860- return ( ) => {
861- observer . unobserve ( element ) ;
850+ if ( ReactNativeFeatureFlags . utilizeTokensInIntersectionObserver ( ) ) {
851+ it ( 'should not retain initial children of observed targets' , ( ) => {
852+ const root = Fantom . createRoot ( ) ;
853+ observer = new IntersectionObserver ( ( ) => { } ) ;
854+
855+ const [ getReferenceCount , ref ] = createShadowNodeReferenceCountingRef ( ) ;
856+
857+ const observeRef : React . RefSetter <
858+ React . ElementRef < typeof View > ,
859+ > = instance => {
860+ const element = ensureReactNativeElement ( instance ) ;
861+ observer . observe ( element ) ;
862+ return ( ) => {
863+ observer . unobserve ( element ) ;
864+ } ;
862865 } ;
863- } ;
864866
865- function Observe ( { children} : $ReadOnly < { children ?: React . Node } > ) {
866- return < View ref = { observeRef } > { children } </ View > ;
867- }
867+ function Observe ( { children} : $ReadOnly < { children ?: React . Node } > ) {
868+ return < View ref = { observeRef } > { children } </ View > ;
869+ }
868870
869- Fantom . runTask ( ( ) => {
870- root . render (
871- < Observe >
872- < View ref = { ref } />
873- </ Observe > ,
874- ) ;
875- } ) ;
871+ Fantom . runTask ( ( ) => {
872+ root . render (
873+ < Observe >
874+ < View ref = { ref } />
875+ </ Observe > ,
876+ ) ;
877+ } ) ;
876878
877- expect ( getReferenceCount ( ) ) . toBeGreaterThan ( 0 ) ;
879+ expect ( getReferenceCount ( ) ) . toBeGreaterThan ( 0 ) ;
878880
879- Fantom . runTask ( ( ) => {
880- root . render ( < Observe /> ) ;
881+ Fantom . runTask ( ( ) => {
882+ root . render ( < Observe /> ) ;
883+ } ) ;
884+
885+ expect ( getReferenceCount ( ) ) . toBe ( 0 ) ;
881886 } ) ;
887+ }
882888
883- expect ( getReferenceCount ( ) ) . toBe ( 0 ) ;
884- } ) ;
889+ if (
890+ ReactNativeFeatureFlags . enableIntersectionObserverEventLoopIntegration ( )
891+ ) {
892+ it ( 'should NOT report multiple entries when observing a target that exists and we modify it later in the same tick' , ( ) => {
893+ const root = Fantom . createRoot ( {
894+ viewportWidth : 1000 ,
895+ viewportHeight : 1000 ,
896+ } ) ;
885897
886- it ( 'should NOT report multiple entries when observing a target that exists and we modify it later in the same tick' , ( ) => {
887- const root = Fantom . createRoot ( {
888- viewportWidth : 1000 ,
889- viewportHeight : 1000 ,
890- } ) ;
898+ const nodeRef = createRef < HostInstance > ( ) ;
891899
892- const nodeRef = createRef < HostInstance > ( ) ;
900+ function TestComponent ( ) {
901+ const [ showView , setShowView ] = useState ( true ) ;
893902
894- function TestComponent ( ) {
895- const [ showView , setShowView ] = useState ( true ) ;
896-
897- return showView ? (
898- < View
899- onClick = { ( ) => {
900- observer . observe ( ensureReactNativeElement ( nodeRef . current ) ) ;
901- setShowView ( false ) ;
902- } }
903- style = { { width : 100 , height : 100 , backgroundColor : 'red' } }
904- ref = { nodeRef }
905- />
906- ) : null ;
907- }
903+ return showView ? (
904+ < View
905+ onClick = { ( ) => {
906+ observer . observe ( ensureReactNativeElement ( nodeRef . current ) ) ;
907+ setShowView ( false ) ;
908+ } }
909+ style = { { width : 100 , height : 100 , backgroundColor : 'red' } }
910+ ref = { nodeRef }
911+ />
912+ ) : null ;
913+ }
908914
909- Fantom . runTask ( ( ) => {
910- root . render ( < TestComponent /> ) ;
911- } ) ;
915+ Fantom . runTask ( ( ) => {
916+ root . render ( < TestComponent /> ) ;
917+ } ) ;
912918
913- const node = ensureReactNativeElement ( nodeRef . current ) ;
919+ const node = ensureReactNativeElement ( nodeRef . current ) ;
914920
915- expect ( node . isConnected ) . toBe ( true ) ;
921+ expect ( node . isConnected ) . toBe ( true ) ;
916922
917- const intersectionObserverCallback = jest . fn ( ) ;
923+ const intersectionObserverCallback = jest . fn ( ) ;
918924
919- Fantom . runTask ( ( ) => {
920- observer = new IntersectionObserver ( intersectionObserverCallback ) ;
921- } ) ;
925+ Fantom . runTask ( ( ) => {
926+ observer = new IntersectionObserver ( intersectionObserverCallback ) ;
927+ } ) ;
922928
923- // We use a discrete event to make sure React processes the update in the
924- // same task.
925- Fantom . dispatchNativeEvent ( node , 'click' ) ;
929+ // We use a discrete event to make sure React processes the update in the
930+ // same task.
931+ Fantom . dispatchNativeEvent ( node , 'click' ) ;
926932
927- expect ( node . isConnected ) . toBe ( false ) ;
933+ expect ( node . isConnected ) . toBe ( false ) ;
928934
929- expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
930- const [ entries ] = intersectionObserverCallback . mock . lastCall ;
931- expect ( entries . length ) . toBe ( 1 ) ;
932- expect ( entries [ 0 ] . isIntersecting ) . toBe ( false ) ;
933- } ) ;
935+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
936+ const [ entries ] = intersectionObserverCallback . mock . lastCall ;
937+ expect ( entries . length ) . toBe ( 1 ) ;
938+ expect ( entries [ 0 ] . isIntersecting ) . toBe ( false ) ;
939+ } ) ;
940+ }
934941
935942 describe ( 'rootThreshold' , ( ) => {
936943 it ( 'should report partial intersecting initial state correctly' , ( ) => {
@@ -1578,40 +1585,44 @@ describe('IntersectionObserver', () => {
15781585 expect ( callback ) . not . toHaveBeenCalled ( ) ;
15791586 } ) ;
15801587
1581- it ( 'should not dispatch pending entries when disconnecting' , ( ) => {
1582- const root = Fantom . createRoot ( {
1583- viewportWidth : 1000 ,
1584- viewportHeight : 1000 ,
1585- } ) ;
1588+ if (
1589+ ReactNativeFeatureFlags . enableIntersectionObserverEventLoopIntegration ( )
1590+ ) {
1591+ it ( 'should not dispatch pending entries when disconnecting' , ( ) => {
1592+ const root = Fantom . createRoot ( {
1593+ viewportWidth : 1000 ,
1594+ viewportHeight : 1000 ,
1595+ } ) ;
15861596
1587- const nodeRef = createRef < HostInstance > ( ) ;
1597+ const nodeRef = createRef < HostInstance > ( ) ;
15881598
1589- Fantom . runTask ( ( ) => {
1590- root . render ( < View ref = { nodeRef } style = { { width : 100 , height : 100 } } /> ) ;
1591- } ) ;
1599+ Fantom . runTask ( ( ) => {
1600+ root . render ( < View ref = { nodeRef } style = { { width : 100 , height : 100 } } /> ) ;
1601+ } ) ;
15921602
1593- const node = ensureReactNativeElement ( nodeRef . current ) ;
1603+ const node = ensureReactNativeElement ( nodeRef . current ) ;
15941604
1595- const intersectionObserverCallback = jest . fn ( ) ;
1605+ const intersectionObserverCallback = jest . fn ( ) ;
15961606
1597- Fantom . runTask ( ( ) => {
1598- observer = new IntersectionObserver ( intersectionObserverCallback ) ;
1607+ Fantom . runTask ( ( ) => {
1608+ observer = new IntersectionObserver ( intersectionObserverCallback ) ;
15991609
1600- // At the end of the current tick, we schedule the execution of the
1601- // intersection observer callback with the initial state of the
1602- // target.
1603- observer . observe ( node ) ;
1610+ // At the end of the current tick, we schedule the execution of the
1611+ // intersection observer callback with the initial state of the
1612+ // target.
1613+ observer . observe ( node ) ;
16041614
1605- // This is executed in the next tick, before the intersection observer
1606- // callback is called.
1607- Fantom . scheduleTask ( ( ) => {
1608- expect ( intersectionObserverCallback ) . not . toHaveBeenCalled ( ) ;
1615+ // This is executed in the next tick, before the intersection observer
1616+ // callback is called.
1617+ Fantom . scheduleTask ( ( ) => {
1618+ expect ( intersectionObserverCallback ) . not . toHaveBeenCalled ( ) ;
16091619
1610- observer . disconnect ( ) ;
1620+ observer . disconnect ( ) ;
1621+ } ) ;
16111622 } ) ;
1612- } ) ;
16131623
1614- expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 0 ) ;
1615- } ) ;
1624+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 0 ) ;
1625+ } ) ;
1626+ }
16161627 } ) ;
16171628} ) ;
0 commit comments