@@ -1868,6 +1868,290 @@ describe('IntersectionObserver', () => {
18681868 } ) ;
18691869 } ) ;
18701870
1871+ describe ( 'intersectionRect is relative to root' , ( ) => {
1872+ it ( 'should report intersectionRect for implicit root' , ( ) => {
1873+ const node1Ref = React . createRef < HostInstance > ( ) ;
1874+
1875+ const root = Fantom . createRoot ( {
1876+ viewportWidth : 1000 ,
1877+ viewportHeight : 1000 ,
1878+ } ) ;
1879+
1880+ Fantom . runTask ( ( ) => {
1881+ root . render (
1882+ < >
1883+ < View
1884+ style = { {
1885+ position : 'absolute' ,
1886+ top : - 50 ,
1887+ width : 100 ,
1888+ height : 100 ,
1889+ } }
1890+ ref = { node1Ref }
1891+ />
1892+ </ > ,
1893+ ) ;
1894+ } ) ;
1895+
1896+ const node1 = ensureReactNativeElement ( node1Ref . current ) ;
1897+
1898+ const intersectionObserverCallback = jest . fn ( ) ;
1899+
1900+ Fantom . runTask ( ( ) => {
1901+ observer = new IntersectionObserver ( intersectionObserverCallback ) ;
1902+ observer . observe ( node1 ) ;
1903+ } ) ;
1904+
1905+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
1906+ const [ entries , reportedObserver ] =
1907+ intersectionObserverCallback . mock . lastCall ;
1908+
1909+ expect ( reportedObserver ) . toBe ( observer ) ;
1910+ expect ( entries . length ) . toBe ( 1 ) ;
1911+ expect ( entries [ 0 ] ) . toBeInstanceOf ( IntersectionObserverEntry ) ;
1912+ expect ( entries [ 0 ] . isIntersecting ) . toBe ( true ) ;
1913+ expect ( entries [ 0 ] . intersectionRatio ) . toBe ( 0.5 ) ;
1914+ expect ( entries [ 0 ] . target ) . toBe ( node1 ) ;
1915+
1916+ expectRectEquals ( entries [ 0 ] . intersectionRect , {
1917+ x : 0 ,
1918+ y : 0 ,
1919+ width : 100 ,
1920+ height : 50 ,
1921+ } ) ;
1922+ expectRectEquals ( entries [ 0 ] . boundingClientRect , {
1923+ x : 0 ,
1924+ y : - 50 ,
1925+ width : 100 ,
1926+ height : 100 ,
1927+ } ) ;
1928+ expectRectEquals ( entries [ 0 ] . rootBounds , {
1929+ x : 0 ,
1930+ y : 0 ,
1931+ width : 1000 ,
1932+ height : 1000 ,
1933+ } ) ;
1934+ } ) ;
1935+
1936+ it ( 'should report intersectionRect for explicit root' , ( ) => {
1937+ const node1Ref = React . createRef < HostInstance > ( ) ;
1938+ const node2Ref = React . createRef < HostInstance > ( ) ;
1939+
1940+ const root = Fantom . createRoot ( {
1941+ viewportWidth : 1000 ,
1942+ viewportHeight : 1000 ,
1943+ } ) ;
1944+
1945+ Fantom . runTask ( ( ) => {
1946+ root . render (
1947+ < >
1948+ < View
1949+ style = { {
1950+ position : 'relative' ,
1951+ marginTop : - 50 ,
1952+ width : 500 ,
1953+ height : 500 ,
1954+ } }
1955+ ref = { node1Ref } >
1956+ < View
1957+ style = { {
1958+ position : 'absolute' ,
1959+ width : 100 ,
1960+ height : 100 ,
1961+ top : - 50 ,
1962+ } }
1963+ ref = { node2Ref }
1964+ />
1965+ </ View >
1966+ </ > ,
1967+ ) ;
1968+ } ) ;
1969+
1970+ const node1 = ensureReactNativeElement ( node1Ref . current ) ;
1971+ const node2 = ensureReactNativeElement ( node2Ref . current ) ;
1972+
1973+ const intersectionObserverCallback = jest . fn ( ) ;
1974+
1975+ Fantom . runTask ( ( ) => {
1976+ observer = new IntersectionObserver ( intersectionObserverCallback , {
1977+ root : node1 ,
1978+ } ) ;
1979+
1980+ observer . observe ( node2 ) ;
1981+ } ) ;
1982+
1983+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
1984+ const [ entries , reportedObserver ] =
1985+ intersectionObserverCallback . mock . lastCall ;
1986+
1987+ expect ( reportedObserver ) . toBe ( observer ) ;
1988+ expect ( entries . length ) . toBe ( 1 ) ;
1989+
1990+ expect ( entries [ 0 ] ) . toBeInstanceOf ( IntersectionObserverEntry ) ;
1991+ expectRectEquals ( entries [ 0 ] . intersectionRect , {
1992+ x : 0 ,
1993+ y : - 50 ,
1994+ width : 100 ,
1995+ height : 50 ,
1996+ } ) ;
1997+ expectRectEquals ( entries [ 0 ] . boundingClientRect , {
1998+ x : 0 ,
1999+ y : - 100 ,
2000+ width : 100 ,
2001+ height : 100 ,
2002+ } ) ;
2003+ expectRectEquals ( entries [ 0 ] . rootBounds , {
2004+ x : 0 ,
2005+ y : - 50 ,
2006+ width : 500 ,
2007+ height : 500 ,
2008+ } ) ;
2009+ expect ( entries [ 0 ] . isIntersecting ) . toBe ( true ) ;
2010+ expect ( entries [ 0 ] . intersectionRatio ) . toBe ( 0.5 ) ;
2011+ expect ( entries [ 0 ] . target ) . toBe ( node2 ) ;
2012+ } ) ;
2013+ } ) ;
2014+
2015+ describe ( 'edge-adjacent intersection' , ( ) => {
2016+ it ( 'should report edge intersect with implicit root' , ( ) => {
2017+ const node1Ref = React . createRef < HostInstance > ( ) ;
2018+
2019+ const root = Fantom . createRoot ( {
2020+ viewportWidth : 1000 ,
2021+ viewportHeight : 1000 ,
2022+ } ) ;
2023+
2024+ Fantom . runTask ( ( ) => {
2025+ root . render (
2026+ < >
2027+ < View
2028+ style = { {
2029+ position : 'absolute' ,
2030+ top : - 100 ,
2031+ width : 100 ,
2032+ height : 100 ,
2033+ } }
2034+ ref = { node1Ref }
2035+ />
2036+ </ > ,
2037+ ) ;
2038+ } ) ;
2039+
2040+ const node1 = ensureReactNativeElement ( node1Ref . current ) ;
2041+
2042+ const intersectionObserverCallback = jest . fn ( ) ;
2043+
2044+ Fantom . runTask ( ( ) => {
2045+ observer = new IntersectionObserver ( intersectionObserverCallback ) ;
2046+ observer . observe ( node1 ) ;
2047+ } ) ;
2048+
2049+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
2050+ const [ entries , reportedObserver ] =
2051+ intersectionObserverCallback . mock . lastCall ;
2052+
2053+ expect ( reportedObserver ) . toBe ( observer ) ;
2054+ expect ( entries . length ) . toBe ( 1 ) ;
2055+ expect ( entries [ 0 ] ) . toBeInstanceOf ( IntersectionObserverEntry ) ;
2056+ expect ( entries [ 0 ] . isIntersecting ) . toBe ( true ) ;
2057+ expect ( entries [ 0 ] . intersectionRatio ) . toBe ( 0 ) ;
2058+ expect ( entries [ 0 ] . target ) . toBe ( node1 ) ;
2059+
2060+ expectRectEquals ( entries [ 0 ] . intersectionRect , {
2061+ x : 0 ,
2062+ y : 0 ,
2063+ width : 100 ,
2064+ height : 0 ,
2065+ } ) ;
2066+ expectRectEquals ( entries [ 0 ] . boundingClientRect , {
2067+ x : 0 ,
2068+ y : - 100 ,
2069+ width : 100 ,
2070+ height : 100 ,
2071+ } ) ;
2072+ expectRectEquals ( entries [ 0 ] . rootBounds , {
2073+ x : 0 ,
2074+ y : 0 ,
2075+ width : 1000 ,
2076+ height : 1000 ,
2077+ } ) ;
2078+ } ) ;
2079+
2080+ it ( 'should report edge-adjacent views with zero intersection area' , ( ) => {
2081+ const node1Ref = React . createRef < HostInstance > ( ) ;
2082+ const node2Ref = React . createRef < HostInstance > ( ) ;
2083+
2084+ const root = Fantom . createRoot ( {
2085+ viewportWidth : 1000 ,
2086+ viewportHeight : 1000 ,
2087+ } ) ;
2088+
2089+ Fantom . runTask ( ( ) => {
2090+ root . render (
2091+ < >
2092+ < View
2093+ style = { {
2094+ position : 'relative' ,
2095+ marginTop : 100 ,
2096+ marginLeft : 100 ,
2097+ width : 100 ,
2098+ height : 100 ,
2099+ } }
2100+ ref = { node1Ref } >
2101+ < View
2102+ style = { { position : 'absolute' , width : 50 , height : 50 , top : - 50 } }
2103+ ref = { node2Ref }
2104+ />
2105+ </ View >
2106+ </ > ,
2107+ ) ;
2108+ } ) ;
2109+
2110+ const node1 = ensureReactNativeElement ( node1Ref . current ) ;
2111+ const node2 = ensureReactNativeElement ( node2Ref . current ) ;
2112+
2113+ const intersectionObserverCallback = jest . fn ( ) ;
2114+
2115+ Fantom . runTask ( ( ) => {
2116+ observer = new IntersectionObserver ( intersectionObserverCallback , {
2117+ root : node1 ,
2118+ } ) ;
2119+
2120+ observer . observe ( node2 ) ;
2121+ } ) ;
2122+
2123+ expect ( intersectionObserverCallback ) . toHaveBeenCalledTimes ( 1 ) ;
2124+ const [ entries , reportedObserver ] =
2125+ intersectionObserverCallback . mock . lastCall ;
2126+
2127+ expect ( reportedObserver ) . toBe ( observer ) ;
2128+ expect ( entries . length ) . toBe ( 1 ) ;
2129+ expect ( entries [ 0 ] ) . toBeInstanceOf ( IntersectionObserverEntry ) ;
2130+ expect ( entries [ 0 ] . isIntersecting ) . toBe ( true ) ;
2131+ expect ( entries [ 0 ] . intersectionRatio ) . toBe ( 0 ) ;
2132+ expect ( entries [ 0 ] . target ) . toBe ( node2 ) ;
2133+
2134+ expectRectEquals ( entries [ 0 ] . intersectionRect , {
2135+ x : 100 ,
2136+ y : 100 ,
2137+ width : 50 ,
2138+ height : 0 ,
2139+ } ) ;
2140+ expectRectEquals ( entries [ 0 ] . boundingClientRect , {
2141+ x : 100 ,
2142+ y : 50 ,
2143+ width : 50 ,
2144+ height : 50 ,
2145+ } ) ;
2146+ expectRectEquals ( entries [ 0 ] . rootBounds , {
2147+ x : 100 ,
2148+ y : 100 ,
2149+ width : 100 ,
2150+ height : 100 ,
2151+ } ) ;
2152+ } ) ;
2153+ } ) ;
2154+
18712155 describe ( 'clipping behavior' , ( ) => {
18722156 it ( 'should report intersection for clipping ancestor' , ( ) => {
18732157 const nodeRef = React . createRef < HostInstance > ( ) ;
0 commit comments