@@ -1561,4 +1561,168 @@ describe('reparenting', () => {
1561
1561
'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}' ,
1562
1562
] ) ;
1563
1563
} ) ;
1564
+
1565
+ test ( 'parent-child switching from flattened-unflattened to unflattened-flattened and grandchild is culled' , ( ) => {
1566
+ const root = Fantom . createRoot ( { viewportWidth : 100 , viewportHeight : 100 } ) ;
1567
+
1568
+ // First render unflattened view container with flattened child that has a culled grandchild.
1569
+ Fantom . runTask ( ( ) => {
1570
+ root . render (
1571
+ < ScrollView
1572
+ style = { { height : 100 , width : 100 } }
1573
+ contentOffset = { { x : 0 , y : 60 } } >
1574
+ < View
1575
+ style = { {
1576
+ marginTop : 100 ,
1577
+ } } >
1578
+ < View
1579
+ style = { {
1580
+ marginTop : 50 ,
1581
+ opacity : 0 ,
1582
+ } } >
1583
+ < View
1584
+ nativeID = { 'grandchild' }
1585
+ style = { { height : 10 , width : 10 , marginTop : 11 } }
1586
+ />
1587
+ </ View >
1588
+ </ View >
1589
+ </ ScrollView > ,
1590
+ ) ;
1591
+ } ) ;
1592
+
1593
+ // Note that `grandchild` is not mounted.
1594
+ expect ( root . takeMountingManagerLogs ( ) ) . toEqual ( [
1595
+ 'Update {type: "RootView", nativeID: (root)}' ,
1596
+ 'Create {type: "ScrollView", nativeID: (N/A)}' ,
1597
+ 'Create {type: "View", nativeID: (N/A)}' ,
1598
+ 'Create {type: "View", nativeID: (N/A)}' ,
1599
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1600
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1601
+ 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}' ,
1602
+ ] ) ;
1603
+
1604
+ let maybeNode = null ;
1605
+
1606
+ // Now change unflattened view container to flattened and change its child to be unflattened.
1607
+ Fantom . runTask ( ( ) => {
1608
+ root . render (
1609
+ < ScrollView
1610
+ style = { { height : 100 , width : 100 } }
1611
+ ref = { node => {
1612
+ maybeNode = node ;
1613
+ } }
1614
+ contentOffset = { { x : 0 , y : 60 } } >
1615
+ < View
1616
+ style = { {
1617
+ marginTop : 100 ,
1618
+ opacity : 0 ,
1619
+ } } >
1620
+ < View
1621
+ style = { {
1622
+ marginTop : 50 ,
1623
+ } } >
1624
+ < View
1625
+ nativeID = { 'grandchild' }
1626
+ style = { { height : 10 , width : 10 , marginTop : 11 } }
1627
+ />
1628
+ </ View >
1629
+ </ View >
1630
+ </ ScrollView > ,
1631
+ ) ;
1632
+ } ) ;
1633
+
1634
+ // Note that `grandchild` is not mounted.
1635
+ expect ( root . takeMountingManagerLogs ( ) ) . toEqual ( [
1636
+ 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1637
+ 'Delete {type: "View", nativeID: (N/A)}' ,
1638
+ 'Create {type: "View", nativeID: (N/A)}' ,
1639
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1640
+ ] ) ;
1641
+
1642
+ const element = ensureInstance ( maybeNode , ReactNativeElement ) ;
1643
+
1644
+ // Scroll to reveal grandchild.
1645
+ Fantom . scrollTo ( element , {
1646
+ x : 0 ,
1647
+ y : 70 ,
1648
+ } ) ;
1649
+
1650
+ expect ( root . takeMountingManagerLogs ( ) ) . toEqual ( [
1651
+ 'Update {type: "ScrollView", nativeID: (N/A)}' ,
1652
+ 'Create {type: "View", nativeID: "grandchild"}' ,
1653
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}' ,
1654
+ ] ) ;
1655
+ } ) ;
1656
+
1657
+ test ( 'parent-child switching from flattened-unflattened to unflattened-flattened' , ( ) => {
1658
+ const root = Fantom . createRoot ( { viewportWidth : 100 , viewportHeight : 100 } ) ;
1659
+
1660
+ // First create a view hierarchy where parent is flattened but child is not.
1661
+ // `grandchild` is not culled.
1662
+ Fantom . runTask ( ( ) => {
1663
+ root . render (
1664
+ < ScrollView
1665
+ style = { { height : 100 , width : 100 } }
1666
+ contentOffset = { { x : 0 , y : 60 } } >
1667
+ < View
1668
+ style = { {
1669
+ marginTop : 100 ,
1670
+ } } >
1671
+ < View
1672
+ style = { {
1673
+ marginTop : 50 ,
1674
+ opacity : 0 ,
1675
+ } } >
1676
+ < View nativeID = { 'grandchild' } style = { { height : 10 , width : 10 } } />
1677
+ </ View >
1678
+ </ View >
1679
+ </ ScrollView > ,
1680
+ ) ;
1681
+ } ) ;
1682
+
1683
+ expect ( root . takeMountingManagerLogs ( ) ) . toEqual ( [
1684
+ 'Update {type: "RootView", nativeID: (root)}' ,
1685
+ 'Create {type: "ScrollView", nativeID: (N/A)}' ,
1686
+ 'Create {type: "View", nativeID: (N/A)}' ,
1687
+ 'Create {type: "View", nativeID: (N/A)}' ,
1688
+ 'Create {type: "View", nativeID: "grandchild"}' ,
1689
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}' ,
1690
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1691
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1692
+ 'Insert {type: "ScrollView", parentNativeID: (root), index: 0, nativeID: (N/A)}' ,
1693
+ ] ) ;
1694
+
1695
+ // Now switch parent to be unflattened and child to be flattened.
1696
+ // `grandchild` remains visible.
1697
+ Fantom . runTask ( ( ) => {
1698
+ root . render (
1699
+ < ScrollView
1700
+ style = { { height : 100 , width : 100 } }
1701
+ contentOffset = { { x : 0 , y : 60 } } >
1702
+ < View
1703
+ style = { {
1704
+ marginTop : 100 ,
1705
+ opacity : 0 ,
1706
+ } } >
1707
+ < View
1708
+ style = { {
1709
+ marginTop : 50 ,
1710
+ } } >
1711
+ < View nativeID = { 'grandchild' } style = { { height : 10 , width : 10 } } />
1712
+ </ View >
1713
+ </ View >
1714
+ </ ScrollView > ,
1715
+ ) ;
1716
+ } ) ;
1717
+
1718
+ expect ( root . takeMountingManagerLogs ( ) ) . toEqual ( [
1719
+ 'Update {type: "View", nativeID: "grandchild"}' ,
1720
+ 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1721
+ 'Remove {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}' ,
1722
+ 'Delete {type: "View", nativeID: (N/A)}' ,
1723
+ 'Create {type: "View", nativeID: (N/A)}' ,
1724
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: (N/A)}' ,
1725
+ 'Insert {type: "View", parentNativeID: (N/A), index: 0, nativeID: "grandchild"}' ,
1726
+ ] ) ;
1727
+ } ) ;
1564
1728
} ) ;
0 commit comments