How to use getRemainingWorkInPrimaryTree method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberBeginWork.new.js

Source:ReactFiberBeginWork.new.js Github

copy

Full Screen

...1569 suspenseContext,1570 (ForceSuspenseFallback: SuspenseContext),1571 );1572}1573function getRemainingWorkInPrimaryTree(1574 current: Fiber,1575 workInProgress: Fiber,1576 renderExpirationTime,1577) {1578 const currentChildExpirationTime = current.childExpirationTime;1579 const currentSuspenseState: SuspenseState = current.memoizedState;1580 if (currentSuspenseState !== null) {1581 // This boundary already timed out. Check if this render includes the level1582 // that previously suspended.1583 const baseTime = currentSuspenseState.baseTime;1584 if (baseTime !== NoWork && baseTime < renderExpirationTime) {1585 // There's pending work at a lower level that might now be unblocked.1586 return baseTime;1587 }1588 }1589 if (currentChildExpirationTime < renderExpirationTime) {1590 // The highest priority remaining work is not part of this render. So the1591 // remaining work has not changed.1592 return currentChildExpirationTime;1593 }1594 if ((workInProgress.mode & BlockingMode) !== NoMode) {1595 // The highest priority remaining work is part of this render. Since we only1596 // keep track of the highest level, we don't know if there's a lower1597 // priority level scheduled. As a compromise, we'll render at the lowest1598 // known level in the entire tree, since that will include everything.1599 // TODO: If expirationTime were a bitmask where each bit represents a1600 // separate task thread, this would be: currentChildBits & ~renderBits1601 const root = getWorkInProgressRoot();1602 if (root !== null) {1603 const lastPendingTime = root.lastPendingTime;1604 if (lastPendingTime < renderExpirationTime) {1605 return lastPendingTime;1606 }1607 }1608 }1609 // In legacy mode, there's no work left.1610 return NoWork;1611}1612function updateSuspenseComponent(1613 current,1614 workInProgress,1615 renderExpirationTime,1616) {1617 const mode = workInProgress.mode;1618 const nextProps = workInProgress.pendingProps;1619 // This is used by DevTools to force a boundary to suspend.1620 if (__DEV__) {1621 if (shouldSuspend(workInProgress)) {1622 workInProgress.effectTag |= DidCapture;1623 }1624 }1625 let suspenseContext: SuspenseContext = suspenseStackCursor.current;1626 let nextDidTimeout = false;1627 const didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;1628 if (1629 didSuspend ||1630 shouldRemainOnFallback(1631 suspenseContext,1632 current,1633 workInProgress,1634 renderExpirationTime,1635 )1636 ) {1637 // Something in this boundary's subtree already suspended. Switch to1638 // rendering the fallback children.1639 nextDidTimeout = true;1640 workInProgress.effectTag &= ~DidCapture;1641 } else {1642 // Attempting the main content1643 if (1644 current === null ||1645 (current.memoizedState: null | SuspenseState) !== null1646 ) {1647 // This is a new mount or this boundary is already showing a fallback state.1648 // Mark this subtree context as having at least one invisible parent that could1649 // handle the fallback state.1650 // Boundaries without fallbacks or should be avoided are not considered since1651 // they cannot handle preferred fallback states.1652 if (1653 nextProps.fallback !== undefined &&1654 nextProps.unstable_avoidThisFallback !== true1655 ) {1656 suspenseContext = addSubtreeSuspenseContext(1657 suspenseContext,1658 InvisibleParentSuspenseContext,1659 );1660 }1661 }1662 }1663 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);1664 pushSuspenseContext(workInProgress, suspenseContext);1665 // This next part is a bit confusing. If the children timeout, we switch to1666 // showing the fallback children in place of the "primary" children.1667 // However, we don't want to delete the primary children because then their1668 // state will be lost (both the React state and the host state, e.g.1669 // uncontrolled form inputs). Instead we keep them mounted and hide them.1670 // Both the fallback children AND the primary children are rendered at the1671 // same time. Once the primary children are un-suspended, we can delete1672 // the fallback children — don't need to preserve their state.1673 //1674 // The two sets of children are siblings in the host environment, but1675 // semantically, for purposes of reconciliation, they are two separate sets.1676 // So we store them using two fragment fibers.1677 //1678 // However, we want to avoid allocating extra fibers for every placeholder.1679 // They're only necessary when the children time out, because that's the1680 // only time when both sets are mounted.1681 //1682 // So, the extra fragment fibers are only used if the children time out.1683 // Otherwise, we render the primary children directly. This requires some1684 // custom reconciliation logic to preserve the state of the primary1685 // children. It's essentially a very basic form of re-parenting.1686 if (current === null) {1687 // If we're currently hydrating, try to hydrate this boundary.1688 // But only if this has a fallback.1689 if (nextProps.fallback !== undefined) {1690 tryToClaimNextHydratableInstance(workInProgress);1691 // This could've been a dehydrated suspense component.1692 if (enableSuspenseServerRenderer) {1693 const suspenseState: null | SuspenseState =1694 workInProgress.memoizedState;1695 if (suspenseState !== null) {1696 const dehydrated = suspenseState.dehydrated;1697 if (dehydrated !== null) {1698 return mountDehydratedSuspenseComponent(1699 workInProgress,1700 dehydrated,1701 renderExpirationTime,1702 );1703 }1704 }1705 }1706 }1707 // This is the initial mount. This branch is pretty simple because there's1708 // no previous state that needs to be preserved.1709 if (nextDidTimeout) {1710 // Mount separate fragments for primary and fallback children.1711 const nextFallbackChildren = nextProps.fallback;1712 const primaryChildFragment = createFiberFromFragment(1713 null,1714 mode,1715 NoWork,1716 null,1717 );1718 primaryChildFragment.return = workInProgress;1719 if ((workInProgress.mode & BlockingMode) === NoMode) {1720 // Outside of blocking mode, we commit the effects from the1721 // partially completed, timed-out tree, too.1722 const progressedState: SuspenseState = workInProgress.memoizedState;1723 const progressedPrimaryChild: Fiber | null =1724 progressedState !== null1725 ? (workInProgress.child: any).child1726 : (workInProgress.child: any);1727 primaryChildFragment.child = progressedPrimaryChild;1728 let progressedChild = progressedPrimaryChild;1729 while (progressedChild !== null) {1730 progressedChild.return = primaryChildFragment;1731 progressedChild = progressedChild.sibling;1732 }1733 }1734 const fallbackChildFragment = createFiberFromFragment(1735 nextFallbackChildren,1736 mode,1737 renderExpirationTime,1738 null,1739 );1740 fallbackChildFragment.return = workInProgress;1741 primaryChildFragment.sibling = fallbackChildFragment;1742 // Skip the primary children, and continue working on the1743 // fallback children.1744 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);1745 workInProgress.child = primaryChildFragment;1746 return fallbackChildFragment;1747 } else {1748 // Mount the primary children without an intermediate fragment fiber.1749 const nextPrimaryChildren = nextProps.children;1750 workInProgress.memoizedState = null;1751 return (workInProgress.child = mountChildFibers(1752 workInProgress,1753 null,1754 nextPrimaryChildren,1755 renderExpirationTime,1756 ));1757 }1758 } else {1759 // This is an update. This branch is more complicated because we need to1760 // ensure the state of the primary children is preserved.1761 const prevState: null | SuspenseState = current.memoizedState;1762 if (prevState !== null) {1763 if (enableSuspenseServerRenderer) {1764 const dehydrated = prevState.dehydrated;1765 if (dehydrated !== null) {1766 if (!didSuspend) {1767 return updateDehydratedSuspenseComponent(1768 current,1769 workInProgress,1770 dehydrated,1771 prevState,1772 renderExpirationTime,1773 );1774 } else if (1775 (workInProgress.memoizedState: null | SuspenseState) !== null1776 ) {1777 // Something suspended and we should still be in dehydrated mode.1778 // Leave the existing child in place.1779 workInProgress.child = current.child;1780 // The dehydrated completion pass expects this flag to be there1781 // but the normal suspense pass doesn't.1782 workInProgress.effectTag |= DidCapture;1783 return null;1784 } else {1785 // Suspended but we should no longer be in dehydrated mode.1786 // Therefore we now have to render the fallback. Wrap the children1787 // in a fragment fiber to keep them separate from the fallback1788 // children.1789 const nextFallbackChildren = nextProps.fallback;1790 const primaryChildFragment = createFiberFromFragment(1791 // It shouldn't matter what the pending props are because we aren't1792 // going to render this fragment.1793 null,1794 mode,1795 NoWork,1796 null,1797 );1798 primaryChildFragment.return = workInProgress;1799 // This is always null since we never want the previous child1800 // that we're not going to hydrate.1801 primaryChildFragment.child = null;1802 if ((workInProgress.mode & BlockingMode) === NoMode) {1803 // Outside of blocking mode, we commit the effects from the1804 // partially completed, timed-out tree, too.1805 let progressedChild = (primaryChildFragment.child =1806 workInProgress.child);1807 while (progressedChild !== null) {1808 progressedChild.return = primaryChildFragment;1809 progressedChild = progressedChild.sibling;1810 }1811 } else {1812 // We will have dropped the effect list which contains the deletion.1813 // We need to reconcile to delete the current child.1814 reconcileChildFibers(1815 workInProgress,1816 current.child,1817 null,1818 renderExpirationTime,1819 );1820 }1821 // Because primaryChildFragment is a new fiber that we're inserting as the1822 // parent of a new tree, we need to set its treeBaseDuration.1823 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1824 // treeBaseDuration is the sum of all the child tree base durations.1825 let treeBaseDuration = 0;1826 let hiddenChild = primaryChildFragment.child;1827 while (hiddenChild !== null) {1828 treeBaseDuration += hiddenChild.treeBaseDuration;1829 hiddenChild = hiddenChild.sibling;1830 }1831 primaryChildFragment.treeBaseDuration = treeBaseDuration;1832 }1833 // Create a fragment from the fallback children, too.1834 const fallbackChildFragment = createFiberFromFragment(1835 nextFallbackChildren,1836 mode,1837 renderExpirationTime,1838 null,1839 );1840 fallbackChildFragment.return = workInProgress;1841 primaryChildFragment.sibling = fallbackChildFragment;1842 fallbackChildFragment.effectTag |= Placement;1843 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1844 current,1845 workInProgress,1846 renderExpirationTime,1847 );1848 workInProgress.memoizedState = updateSuspenseState(1849 current.memoizedState,1850 renderExpirationTime,1851 );1852 workInProgress.child = primaryChildFragment;1853 // Skip the primary children, and continue working on the1854 // fallback children.1855 return fallbackChildFragment;1856 }1857 }1858 }1859 // The current tree already timed out. That means each child set is1860 // wrapped in a fragment fiber.1861 const currentPrimaryChildFragment: Fiber = (current.child: any);1862 const currentFallbackChildFragment: Fiber = (currentPrimaryChildFragment.sibling: any);1863 if (nextDidTimeout) {1864 // Still timed out. Reuse the current primary children by cloning1865 // its fragment. We're going to skip over these entirely.1866 const nextFallbackChildren = nextProps.fallback;1867 const primaryChildFragment = createWorkInProgress(1868 currentPrimaryChildFragment,1869 currentPrimaryChildFragment.pendingProps,1870 );1871 primaryChildFragment.return = workInProgress;1872 if ((workInProgress.mode & BlockingMode) === NoMode) {1873 // Outside of blocking mode, we commit the effects from the1874 // partially completed, timed-out tree, too.1875 const progressedState: SuspenseState = workInProgress.memoizedState;1876 const progressedPrimaryChild: Fiber | null =1877 progressedState !== null1878 ? (workInProgress.child: any).child1879 : (workInProgress.child: any);1880 if (progressedPrimaryChild !== currentPrimaryChildFragment.child) {1881 primaryChildFragment.child = progressedPrimaryChild;1882 let progressedChild = progressedPrimaryChild;1883 while (progressedChild !== null) {1884 progressedChild.return = primaryChildFragment;1885 progressedChild = progressedChild.sibling;1886 }1887 }1888 }1889 // Because primaryChildFragment is a new fiber that we're inserting as the1890 // parent of a new tree, we need to set its treeBaseDuration.1891 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1892 // treeBaseDuration is the sum of all the child tree base durations.1893 let treeBaseDuration = 0;1894 let hiddenChild = primaryChildFragment.child;1895 while (hiddenChild !== null) {1896 treeBaseDuration += hiddenChild.treeBaseDuration;1897 hiddenChild = hiddenChild.sibling;1898 }1899 primaryChildFragment.treeBaseDuration = treeBaseDuration;1900 }1901 // Clone the fallback child fragment, too. These we'll continue1902 // working on.1903 const fallbackChildFragment = createWorkInProgress(1904 currentFallbackChildFragment,1905 nextFallbackChildren,1906 );1907 fallbackChildFragment.return = workInProgress;1908 primaryChildFragment.sibling = fallbackChildFragment;1909 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1910 current,1911 workInProgress,1912 renderExpirationTime,1913 );1914 // Skip the primary children, and continue working on the1915 // fallback children.1916 workInProgress.memoizedState = updateSuspenseState(1917 current.memoizedState,1918 renderExpirationTime,1919 );1920 workInProgress.child = primaryChildFragment;1921 return fallbackChildFragment;1922 } else {1923 // No longer suspended. Switch back to showing the primary children,1924 // and remove the intermediate fragment fiber.1925 const nextPrimaryChildren = nextProps.children;1926 const currentPrimaryChild = currentPrimaryChildFragment.child;1927 const primaryChild = reconcileChildFibers(1928 workInProgress,1929 currentPrimaryChild,1930 nextPrimaryChildren,1931 renderExpirationTime,1932 );1933 // If this render doesn't suspend, we need to delete the fallback1934 // children. Wait until the complete phase, after we've confirmed the1935 // fallback is no longer needed.1936 // TODO: Would it be better to store the fallback fragment on1937 // the stateNode?1938 // Continue rendering the children, like we normally do.1939 workInProgress.memoizedState = null;1940 return (workInProgress.child = primaryChild);1941 }1942 } else {1943 // The current tree has not already timed out. That means the primary1944 // children are not wrapped in a fragment fiber.1945 const currentPrimaryChild = current.child;1946 if (nextDidTimeout) {1947 // Timed out. Wrap the children in a fragment fiber to keep them1948 // separate from the fallback children.1949 const nextFallbackChildren = nextProps.fallback;1950 const primaryChildFragment = createFiberFromFragment(1951 // It shouldn't matter what the pending props are because we aren't1952 // going to render this fragment.1953 null,1954 mode,1955 NoWork,1956 null,1957 );1958 primaryChildFragment.return = workInProgress;1959 primaryChildFragment.child = currentPrimaryChild;1960 if (currentPrimaryChild !== null) {1961 currentPrimaryChild.return = primaryChildFragment;1962 }1963 // Even though we're creating a new fiber, there are no new children,1964 // because we're reusing an already mounted tree. So we don't need to1965 // schedule a placement.1966 // primaryChildFragment.effectTag |= Placement;1967 if ((workInProgress.mode & BlockingMode) === NoMode) {1968 // Outside of blocking mode, we commit the effects from the1969 // partially completed, timed-out tree, too.1970 const progressedState: SuspenseState = workInProgress.memoizedState;1971 const progressedPrimaryChild: Fiber | null =1972 progressedState !== null1973 ? (workInProgress.child: any).child1974 : (workInProgress.child: any);1975 primaryChildFragment.child = progressedPrimaryChild;1976 let progressedChild = progressedPrimaryChild;1977 while (progressedChild !== null) {1978 progressedChild.return = primaryChildFragment;1979 progressedChild = progressedChild.sibling;1980 }1981 }1982 // Because primaryChildFragment is a new fiber that we're inserting as the1983 // parent of a new tree, we need to set its treeBaseDuration.1984 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1985 // treeBaseDuration is the sum of all the child tree base durations.1986 let treeBaseDuration = 0;1987 let hiddenChild = primaryChildFragment.child;1988 while (hiddenChild !== null) {1989 treeBaseDuration += hiddenChild.treeBaseDuration;1990 hiddenChild = hiddenChild.sibling;1991 }1992 primaryChildFragment.treeBaseDuration = treeBaseDuration;1993 }1994 // Create a fragment from the fallback children, too.1995 const fallbackChildFragment = createFiberFromFragment(1996 nextFallbackChildren,1997 mode,1998 renderExpirationTime,1999 null,2000 );2001 fallbackChildFragment.return = workInProgress;2002 primaryChildFragment.sibling = fallbackChildFragment;2003 fallbackChildFragment.effectTag |= Placement;2004 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(2005 current,2006 workInProgress,2007 renderExpirationTime,2008 );2009 // Skip the primary children, and continue working on the2010 // fallback children.2011 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);2012 workInProgress.child = primaryChildFragment;2013 return fallbackChildFragment;2014 } else {2015 // Still haven't timed out. Continue rendering the children, like we2016 // normally do.2017 workInProgress.memoizedState = null;2018 const nextPrimaryChildren = nextProps.children;...

Full Screen

Full Screen

ReactFiberBeginWork.old.js

Source:ReactFiberBeginWork.old.js Github

copy

Full Screen

...1569 suspenseContext,1570 (ForceSuspenseFallback: SuspenseContext),1571 );1572}1573function getRemainingWorkInPrimaryTree(1574 current: Fiber,1575 workInProgress: Fiber,1576 renderExpirationTime,1577) {1578 const currentChildExpirationTime = current.childExpirationTime;1579 const currentSuspenseState: SuspenseState = current.memoizedState;1580 if (currentSuspenseState !== null) {1581 // This boundary already timed out. Check if this render includes the level1582 // that previously suspended.1583 const baseTime = currentSuspenseState.baseTime;1584 if (baseTime !== NoWork && baseTime < renderExpirationTime) {1585 // There's pending work at a lower level that might now be unblocked.1586 return baseTime;1587 }1588 }1589 if (currentChildExpirationTime < renderExpirationTime) {1590 // The highest priority remaining work is not part of this render. So the1591 // remaining work has not changed.1592 return currentChildExpirationTime;1593 }1594 if ((workInProgress.mode & BlockingMode) !== NoMode) {1595 // The highest priority remaining work is part of this render. Since we only1596 // keep track of the highest level, we don't know if there's a lower1597 // priority level scheduled. As a compromise, we'll render at the lowest1598 // known level in the entire tree, since that will include everything.1599 // TODO: If expirationTime were a bitmask where each bit represents a1600 // separate task thread, this would be: currentChildBits & ~renderBits1601 const root = getWorkInProgressRoot();1602 if (root !== null) {1603 const lastPendingTime = root.lastPendingTime;1604 if (lastPendingTime < renderExpirationTime) {1605 return lastPendingTime;1606 }1607 }1608 }1609 // In legacy mode, there's no work left.1610 return NoWork;1611}1612function updateSuspenseComponent(1613 current,1614 workInProgress,1615 renderExpirationTime,1616) {1617 const mode = workInProgress.mode;1618 const nextProps = workInProgress.pendingProps;1619 // This is used by DevTools to force a boundary to suspend.1620 if (__DEV__) {1621 if (shouldSuspend(workInProgress)) {1622 workInProgress.effectTag |= DidCapture;1623 }1624 }1625 let suspenseContext: SuspenseContext = suspenseStackCursor.current;1626 let nextDidTimeout = false;1627 const didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;1628 if (1629 didSuspend ||1630 shouldRemainOnFallback(1631 suspenseContext,1632 current,1633 workInProgress,1634 renderExpirationTime,1635 )1636 ) {1637 // Something in this boundary's subtree already suspended. Switch to1638 // rendering the fallback children.1639 nextDidTimeout = true;1640 workInProgress.effectTag &= ~DidCapture;1641 } else {1642 // Attempting the main content1643 if (1644 current === null ||1645 (current.memoizedState: null | SuspenseState) !== null1646 ) {1647 // This is a new mount or this boundary is already showing a fallback state.1648 // Mark this subtree context as having at least one invisible parent that could1649 // handle the fallback state.1650 // Boundaries without fallbacks or should be avoided are not considered since1651 // they cannot handle preferred fallback states.1652 if (1653 nextProps.fallback !== undefined &&1654 nextProps.unstable_avoidThisFallback !== true1655 ) {1656 suspenseContext = addSubtreeSuspenseContext(1657 suspenseContext,1658 InvisibleParentSuspenseContext,1659 );1660 }1661 }1662 }1663 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);1664 pushSuspenseContext(workInProgress, suspenseContext);1665 // This next part is a bit confusing. If the children timeout, we switch to1666 // showing the fallback children in place of the "primary" children.1667 // However, we don't want to delete the primary children because then their1668 // state will be lost (both the React state and the host state, e.g.1669 // uncontrolled form inputs). Instead we keep them mounted and hide them.1670 // Both the fallback children AND the primary children are rendered at the1671 // same time. Once the primary children are un-suspended, we can delete1672 // the fallback children — don't need to preserve their state.1673 //1674 // The two sets of children are siblings in the host environment, but1675 // semantically, for purposes of reconciliation, they are two separate sets.1676 // So we store them using two fragment fibers.1677 //1678 // However, we want to avoid allocating extra fibers for every placeholder.1679 // They're only necessary when the children time out, because that's the1680 // only time when both sets are mounted.1681 //1682 // So, the extra fragment fibers are only used if the children time out.1683 // Otherwise, we render the primary children directly. This requires some1684 // custom reconciliation logic to preserve the state of the primary1685 // children. It's essentially a very basic form of re-parenting.1686 if (current === null) {1687 // If we're currently hydrating, try to hydrate this boundary.1688 // But only if this has a fallback.1689 if (nextProps.fallback !== undefined) {1690 tryToClaimNextHydratableInstance(workInProgress);1691 // This could've been a dehydrated suspense component.1692 if (enableSuspenseServerRenderer) {1693 const suspenseState: null | SuspenseState =1694 workInProgress.memoizedState;1695 if (suspenseState !== null) {1696 const dehydrated = suspenseState.dehydrated;1697 if (dehydrated !== null) {1698 return mountDehydratedSuspenseComponent(1699 workInProgress,1700 dehydrated,1701 renderExpirationTime,1702 );1703 }1704 }1705 }1706 }1707 // This is the initial mount. This branch is pretty simple because there's1708 // no previous state that needs to be preserved.1709 if (nextDidTimeout) {1710 // Mount separate fragments for primary and fallback children.1711 const nextFallbackChildren = nextProps.fallback;1712 const primaryChildFragment = createFiberFromFragment(1713 null,1714 mode,1715 NoWork,1716 null,1717 );1718 primaryChildFragment.return = workInProgress;1719 if ((workInProgress.mode & BlockingMode) === NoMode) {1720 // Outside of blocking mode, we commit the effects from the1721 // partially completed, timed-out tree, too.1722 const progressedState: SuspenseState = workInProgress.memoizedState;1723 const progressedPrimaryChild: Fiber | null =1724 progressedState !== null1725 ? (workInProgress.child: any).child1726 : (workInProgress.child: any);1727 primaryChildFragment.child = progressedPrimaryChild;1728 let progressedChild = progressedPrimaryChild;1729 while (progressedChild !== null) {1730 progressedChild.return = primaryChildFragment;1731 progressedChild = progressedChild.sibling;1732 }1733 }1734 const fallbackChildFragment = createFiberFromFragment(1735 nextFallbackChildren,1736 mode,1737 renderExpirationTime,1738 null,1739 );1740 fallbackChildFragment.return = workInProgress;1741 primaryChildFragment.sibling = fallbackChildFragment;1742 // Skip the primary children, and continue working on the1743 // fallback children.1744 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);1745 workInProgress.child = primaryChildFragment;1746 return fallbackChildFragment;1747 } else {1748 // Mount the primary children without an intermediate fragment fiber.1749 const nextPrimaryChildren = nextProps.children;1750 workInProgress.memoizedState = null;1751 return (workInProgress.child = mountChildFibers(1752 workInProgress,1753 null,1754 nextPrimaryChildren,1755 renderExpirationTime,1756 ));1757 }1758 } else {1759 // This is an update. This branch is more complicated because we need to1760 // ensure the state of the primary children is preserved.1761 const prevState: null | SuspenseState = current.memoizedState;1762 if (prevState !== null) {1763 if (enableSuspenseServerRenderer) {1764 const dehydrated = prevState.dehydrated;1765 if (dehydrated !== null) {1766 if (!didSuspend) {1767 return updateDehydratedSuspenseComponent(1768 current,1769 workInProgress,1770 dehydrated,1771 prevState,1772 renderExpirationTime,1773 );1774 } else if (1775 (workInProgress.memoizedState: null | SuspenseState) !== null1776 ) {1777 // Something suspended and we should still be in dehydrated mode.1778 // Leave the existing child in place.1779 workInProgress.child = current.child;1780 // The dehydrated completion pass expects this flag to be there1781 // but the normal suspense pass doesn't.1782 workInProgress.effectTag |= DidCapture;1783 return null;1784 } else {1785 // Suspended but we should no longer be in dehydrated mode.1786 // Therefore we now have to render the fallback. Wrap the children1787 // in a fragment fiber to keep them separate from the fallback1788 // children.1789 const nextFallbackChildren = nextProps.fallback;1790 const primaryChildFragment = createFiberFromFragment(1791 // It shouldn't matter what the pending props are because we aren't1792 // going to render this fragment.1793 null,1794 mode,1795 NoWork,1796 null,1797 );1798 primaryChildFragment.return = workInProgress;1799 // This is always null since we never want the previous child1800 // that we're not going to hydrate.1801 primaryChildFragment.child = null;1802 if ((workInProgress.mode & BlockingMode) === NoMode) {1803 // Outside of blocking mode, we commit the effects from the1804 // partially completed, timed-out tree, too.1805 let progressedChild = (primaryChildFragment.child =1806 workInProgress.child);1807 while (progressedChild !== null) {1808 progressedChild.return = primaryChildFragment;1809 progressedChild = progressedChild.sibling;1810 }1811 } else {1812 // We will have dropped the effect list which contains the deletion.1813 // We need to reconcile to delete the current child.1814 reconcileChildFibers(1815 workInProgress,1816 current.child,1817 null,1818 renderExpirationTime,1819 );1820 }1821 // Because primaryChildFragment is a new fiber that we're inserting as the1822 // parent of a new tree, we need to set its treeBaseDuration.1823 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1824 // treeBaseDuration is the sum of all the child tree base durations.1825 let treeBaseDuration = 0;1826 let hiddenChild = primaryChildFragment.child;1827 while (hiddenChild !== null) {1828 treeBaseDuration += hiddenChild.treeBaseDuration;1829 hiddenChild = hiddenChild.sibling;1830 }1831 primaryChildFragment.treeBaseDuration = treeBaseDuration;1832 }1833 // Create a fragment from the fallback children, too.1834 const fallbackChildFragment = createFiberFromFragment(1835 nextFallbackChildren,1836 mode,1837 renderExpirationTime,1838 null,1839 );1840 fallbackChildFragment.return = workInProgress;1841 primaryChildFragment.sibling = fallbackChildFragment;1842 fallbackChildFragment.effectTag |= Placement;1843 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1844 current,1845 workInProgress,1846 renderExpirationTime,1847 );1848 workInProgress.memoizedState = updateSuspenseState(1849 current.memoizedState,1850 renderExpirationTime,1851 );1852 workInProgress.child = primaryChildFragment;1853 // Skip the primary children, and continue working on the1854 // fallback children.1855 return fallbackChildFragment;1856 }1857 }1858 }1859 // The current tree already timed out. That means each child set is1860 // wrapped in a fragment fiber.1861 const currentPrimaryChildFragment: Fiber = (current.child: any);1862 const currentFallbackChildFragment: Fiber = (currentPrimaryChildFragment.sibling: any);1863 if (nextDidTimeout) {1864 // Still timed out. Reuse the current primary children by cloning1865 // its fragment. We're going to skip over these entirely.1866 const nextFallbackChildren = nextProps.fallback;1867 const primaryChildFragment = createWorkInProgress(1868 currentPrimaryChildFragment,1869 currentPrimaryChildFragment.pendingProps,1870 );1871 primaryChildFragment.return = workInProgress;1872 if ((workInProgress.mode & BlockingMode) === NoMode) {1873 // Outside of blocking mode, we commit the effects from the1874 // partially completed, timed-out tree, too.1875 const progressedState: SuspenseState = workInProgress.memoizedState;1876 const progressedPrimaryChild: Fiber | null =1877 progressedState !== null1878 ? (workInProgress.child: any).child1879 : (workInProgress.child: any);1880 if (progressedPrimaryChild !== currentPrimaryChildFragment.child) {1881 primaryChildFragment.child = progressedPrimaryChild;1882 let progressedChild = progressedPrimaryChild;1883 while (progressedChild !== null) {1884 progressedChild.return = primaryChildFragment;1885 progressedChild = progressedChild.sibling;1886 }1887 }1888 }1889 // Because primaryChildFragment is a new fiber that we're inserting as the1890 // parent of a new tree, we need to set its treeBaseDuration.1891 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1892 // treeBaseDuration is the sum of all the child tree base durations.1893 let treeBaseDuration = 0;1894 let hiddenChild = primaryChildFragment.child;1895 while (hiddenChild !== null) {1896 treeBaseDuration += hiddenChild.treeBaseDuration;1897 hiddenChild = hiddenChild.sibling;1898 }1899 primaryChildFragment.treeBaseDuration = treeBaseDuration;1900 }1901 // Clone the fallback child fragment, too. These we'll continue1902 // working on.1903 const fallbackChildFragment = createWorkInProgress(1904 currentFallbackChildFragment,1905 nextFallbackChildren,1906 );1907 fallbackChildFragment.return = workInProgress;1908 primaryChildFragment.sibling = fallbackChildFragment;1909 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1910 current,1911 workInProgress,1912 renderExpirationTime,1913 );1914 // Skip the primary children, and continue working on the1915 // fallback children.1916 workInProgress.memoizedState = updateSuspenseState(1917 current.memoizedState,1918 renderExpirationTime,1919 );1920 workInProgress.child = primaryChildFragment;1921 return fallbackChildFragment;1922 } else {1923 // No longer suspended. Switch back to showing the primary children,1924 // and remove the intermediate fragment fiber.1925 const nextPrimaryChildren = nextProps.children;1926 const currentPrimaryChild = currentPrimaryChildFragment.child;1927 const primaryChild = reconcileChildFibers(1928 workInProgress,1929 currentPrimaryChild,1930 nextPrimaryChildren,1931 renderExpirationTime,1932 );1933 // If this render doesn't suspend, we need to delete the fallback1934 // children. Wait until the complete phase, after we've confirmed the1935 // fallback is no longer needed.1936 // TODO: Would it be better to store the fallback fragment on1937 // the stateNode?1938 // Continue rendering the children, like we normally do.1939 workInProgress.memoizedState = null;1940 return (workInProgress.child = primaryChild);1941 }1942 } else {1943 // The current tree has not already timed out. That means the primary1944 // children are not wrapped in a fragment fiber.1945 const currentPrimaryChild = current.child;1946 if (nextDidTimeout) {1947 // Timed out. Wrap the children in a fragment fiber to keep them1948 // separate from the fallback children.1949 const nextFallbackChildren = nextProps.fallback;1950 const primaryChildFragment = createFiberFromFragment(1951 // It shouldn't matter what the pending props are because we aren't1952 // going to render this fragment.1953 null,1954 mode,1955 NoWork,1956 null,1957 );1958 primaryChildFragment.return = workInProgress;1959 primaryChildFragment.child = currentPrimaryChild;1960 if (currentPrimaryChild !== null) {1961 currentPrimaryChild.return = primaryChildFragment;1962 }1963 // Even though we're creating a new fiber, there are no new children,1964 // because we're reusing an already mounted tree. So we don't need to1965 // schedule a placement.1966 // primaryChildFragment.effectTag |= Placement;1967 if ((workInProgress.mode & BlockingMode) === NoMode) {1968 // Outside of blocking mode, we commit the effects from the1969 // partially completed, timed-out tree, too.1970 const progressedState: SuspenseState = workInProgress.memoizedState;1971 const progressedPrimaryChild: Fiber | null =1972 progressedState !== null1973 ? (workInProgress.child: any).child1974 : (workInProgress.child: any);1975 primaryChildFragment.child = progressedPrimaryChild;1976 let progressedChild = progressedPrimaryChild;1977 while (progressedChild !== null) {1978 progressedChild.return = primaryChildFragment;1979 progressedChild = progressedChild.sibling;1980 }1981 }1982 // Because primaryChildFragment is a new fiber that we're inserting as the1983 // parent of a new tree, we need to set its treeBaseDuration.1984 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1985 // treeBaseDuration is the sum of all the child tree base durations.1986 let treeBaseDuration = 0;1987 let hiddenChild = primaryChildFragment.child;1988 while (hiddenChild !== null) {1989 treeBaseDuration += hiddenChild.treeBaseDuration;1990 hiddenChild = hiddenChild.sibling;1991 }1992 primaryChildFragment.treeBaseDuration = treeBaseDuration;1993 }1994 // Create a fragment from the fallback children, too.1995 const fallbackChildFragment = createFiberFromFragment(1996 nextFallbackChildren,1997 mode,1998 renderExpirationTime,1999 null,2000 );2001 fallbackChildFragment.return = workInProgress;2002 primaryChildFragment.sibling = fallbackChildFragment;2003 fallbackChildFragment.effectTag |= Placement;2004 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(2005 current,2006 workInProgress,2007 renderExpirationTime,2008 );2009 // Skip the primary children, and continue working on the2010 // fallback children.2011 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);2012 workInProgress.child = primaryChildFragment;2013 return fallbackChildFragment;2014 } else {2015 // Still haven't timed out. Continue rendering the children, like we2016 // normally do.2017 workInProgress.memoizedState = null;2018 const nextPrimaryChildren = nextProps.children;...

Full Screen

Full Screen

ReactFiberBeginWork.js

Source:ReactFiberBeginWork.js Github

copy

Full Screen

...1543 suspenseContext,1544 (ForceSuspenseFallback: SuspenseContext),1545 );1546}1547function getRemainingWorkInPrimaryTree(1548 current: Fiber,1549 workInProgress: Fiber,1550 renderExpirationTime,1551) {1552 const currentChildExpirationTime = current.childExpirationTime;1553 const currentSuspenseState: SuspenseState = current.memoizedState;1554 if (currentSuspenseState !== null) {1555 // This boundary already timed out. Check if this render includes the level1556 // that previously suspended.1557 const baseTime = currentSuspenseState.baseTime;1558 if (1559 baseTime !== NoWork &&1560 baseTime < renderExpirationTime &&1561 baseTime > currentChildExpirationTime1562 ) {1563 // There's pending work at a lower level that might now be unblocked.1564 return baseTime;1565 }1566 }1567 if (currentChildExpirationTime < renderExpirationTime) {1568 // The highest priority remaining work is not part of this render. So the1569 // remaining work has not changed.1570 return currentChildExpirationTime;1571 }1572 if ((workInProgress.mode & BlockingMode) !== NoMode) {1573 // The highest priority remaining work is part of this render. Since we only1574 // keep track of the highest level, we don't know if there's a lower1575 // priority level scheduled. As a compromise, we'll render at the lowest1576 // known level in the entire tree, since that will include everything.1577 // TODO: If expirationTime were a bitmask where each bit represents a1578 // separate task thread, this would be: currentChildBits & ~renderBits1579 const root = getWorkInProgressRoot();1580 if (root !== null) {1581 const lastPendingTime = root.lastPendingTime;1582 if (lastPendingTime < renderExpirationTime) {1583 return lastPendingTime;1584 }1585 }1586 }1587 // In legacy mode, there's no work left.1588 return NoWork;1589}1590function updateSuspenseComponent(1591 current,1592 workInProgress,1593 renderExpirationTime,1594) {1595 const mode = workInProgress.mode;1596 const nextProps = workInProgress.pendingProps;1597 // This is used by DevTools to force a boundary to suspend.1598 if (__DEV__) {1599 if (shouldSuspend(workInProgress)) {1600 workInProgress.effectTag |= DidCapture;1601 }1602 }1603 let suspenseContext: SuspenseContext = suspenseStackCursor.current;1604 let nextDidTimeout = false;1605 const didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;1606 if (1607 didSuspend ||1608 shouldRemainOnFallback(1609 suspenseContext,1610 current,1611 workInProgress,1612 renderExpirationTime,1613 )1614 ) {1615 // Something in this boundary's subtree already suspended. Switch to1616 // rendering the fallback children.1617 nextDidTimeout = true;1618 workInProgress.effectTag &= ~DidCapture;1619 } else {1620 // Attempting the main content1621 if (1622 current === null ||1623 (current.memoizedState: null | SuspenseState) !== null1624 ) {1625 // This is a new mount or this boundary is already showing a fallback state.1626 // Mark this subtree context as having at least one invisible parent that could1627 // handle the fallback state.1628 // Boundaries without fallbacks or should be avoided are not considered since1629 // they cannot handle preferred fallback states.1630 if (1631 nextProps.fallback !== undefined &&1632 nextProps.unstable_avoidThisFallback !== true1633 ) {1634 suspenseContext = addSubtreeSuspenseContext(1635 suspenseContext,1636 InvisibleParentSuspenseContext,1637 );1638 }1639 }1640 }1641 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);1642 pushSuspenseContext(workInProgress, suspenseContext);1643 // This next part is a bit confusing. If the children timeout, we switch to1644 // showing the fallback children in place of the "primary" children.1645 // However, we don't want to delete the primary children because then their1646 // state will be lost (both the React state and the host state, e.g.1647 // uncontrolled form inputs). Instead we keep them mounted and hide them.1648 // Both the fallback children AND the primary children are rendered at the1649 // same time. Once the primary children are un-suspended, we can delete1650 // the fallback children — don't need to preserve their state.1651 //1652 // The two sets of children are siblings in the host environment, but1653 // semantically, for purposes of reconciliation, they are two separate sets.1654 // So we store them using two fragment fibers.1655 //1656 // However, we want to avoid allocating extra fibers for every placeholder.1657 // They're only necessary when the children time out, because that's the1658 // only time when both sets are mounted.1659 //1660 // So, the extra fragment fibers are only used if the children time out.1661 // Otherwise, we render the primary children directly. This requires some1662 // custom reconciliation logic to preserve the state of the primary1663 // children. It's essentially a very basic form of re-parenting.1664 if (current === null) {1665 // If we're currently hydrating, try to hydrate this boundary.1666 // But only if this has a fallback.1667 if (nextProps.fallback !== undefined) {1668 tryToClaimNextHydratableInstance(workInProgress);1669 // This could've been a dehydrated suspense component.1670 if (enableSuspenseServerRenderer) {1671 const suspenseState: null | SuspenseState =1672 workInProgress.memoizedState;1673 if (suspenseState !== null) {1674 const dehydrated = suspenseState.dehydrated;1675 if (dehydrated !== null) {1676 return mountDehydratedSuspenseComponent(1677 workInProgress,1678 dehydrated,1679 renderExpirationTime,1680 );1681 }1682 }1683 }1684 }1685 // This is the initial mount. This branch is pretty simple because there's1686 // no previous state that needs to be preserved.1687 if (nextDidTimeout) {1688 // Mount separate fragments for primary and fallback children.1689 const nextFallbackChildren = nextProps.fallback;1690 const primaryChildFragment = createFiberFromFragment(1691 null,1692 mode,1693 NoWork,1694 null,1695 );1696 primaryChildFragment.return = workInProgress;1697 if ((workInProgress.mode & BlockingMode) === NoMode) {1698 // Outside of blocking mode, we commit the effects from the1699 // partially completed, timed-out tree, too.1700 const progressedState: SuspenseState = workInProgress.memoizedState;1701 const progressedPrimaryChild: Fiber | null =1702 progressedState !== null1703 ? (workInProgress.child: any).child1704 : (workInProgress.child: any);1705 primaryChildFragment.child = progressedPrimaryChild;1706 let progressedChild = progressedPrimaryChild;1707 while (progressedChild !== null) {1708 progressedChild.return = primaryChildFragment;1709 progressedChild = progressedChild.sibling;1710 }1711 }1712 const fallbackChildFragment = createFiberFromFragment(1713 nextFallbackChildren,1714 mode,1715 renderExpirationTime,1716 null,1717 );1718 fallbackChildFragment.return = workInProgress;1719 primaryChildFragment.sibling = fallbackChildFragment;1720 // Skip the primary children, and continue working on the1721 // fallback children.1722 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);1723 workInProgress.child = primaryChildFragment;1724 return fallbackChildFragment;1725 } else {1726 // Mount the primary children without an intermediate fragment fiber.1727 const nextPrimaryChildren = nextProps.children;1728 workInProgress.memoizedState = null;1729 return (workInProgress.child = mountChildFibers(1730 workInProgress,1731 null,1732 nextPrimaryChildren,1733 renderExpirationTime,1734 ));1735 }1736 } else {1737 // This is an update. This branch is more complicated because we need to1738 // ensure the state of the primary children is preserved.1739 const prevState: null | SuspenseState = current.memoizedState;1740 if (prevState !== null) {1741 if (enableSuspenseServerRenderer) {1742 const dehydrated = prevState.dehydrated;1743 if (dehydrated !== null) {1744 if (!didSuspend) {1745 return updateDehydratedSuspenseComponent(1746 current,1747 workInProgress,1748 dehydrated,1749 prevState,1750 renderExpirationTime,1751 );1752 } else if (1753 (workInProgress.memoizedState: null | SuspenseState) !== null1754 ) {1755 // Something suspended and we should still be in dehydrated mode.1756 // Leave the existing child in place.1757 workInProgress.child = current.child;1758 // The dehydrated completion pass expects this flag to be there1759 // but the normal suspense pass doesn't.1760 workInProgress.effectTag |= DidCapture;1761 return null;1762 } else {1763 // Suspended but we should no longer be in dehydrated mode.1764 // Therefore we now have to render the fallback. Wrap the children1765 // in a fragment fiber to keep them separate from the fallback1766 // children.1767 const nextFallbackChildren = nextProps.fallback;1768 const primaryChildFragment = createFiberFromFragment(1769 // It shouldn't matter what the pending props are because we aren't1770 // going to render this fragment.1771 null,1772 mode,1773 NoWork,1774 null,1775 );1776 primaryChildFragment.return = workInProgress;1777 // This is always null since we never want the previous child1778 // that we're not going to hydrate.1779 primaryChildFragment.child = null;1780 if ((workInProgress.mode & BlockingMode) === NoMode) {1781 // Outside of blocking mode, we commit the effects from the1782 // partially completed, timed-out tree, too.1783 let progressedChild = (primaryChildFragment.child =1784 workInProgress.child);1785 while (progressedChild !== null) {1786 progressedChild.return = primaryChildFragment;1787 progressedChild = progressedChild.sibling;1788 }1789 } else {1790 // We will have dropped the effect list which contains the deletion.1791 // We need to reconcile to delete the current child.1792 reconcileChildFibers(1793 workInProgress,1794 current.child,1795 null,1796 renderExpirationTime,1797 );1798 }1799 // Because primaryChildFragment is a new fiber that we're inserting as the1800 // parent of a new tree, we need to set its treeBaseDuration.1801 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1802 // treeBaseDuration is the sum of all the child tree base durations.1803 let treeBaseDuration = 0;1804 let hiddenChild = primaryChildFragment.child;1805 while (hiddenChild !== null) {1806 treeBaseDuration += hiddenChild.treeBaseDuration;1807 hiddenChild = hiddenChild.sibling;1808 }1809 primaryChildFragment.treeBaseDuration = treeBaseDuration;1810 }1811 // Create a fragment from the fallback children, too.1812 const fallbackChildFragment = createFiberFromFragment(1813 nextFallbackChildren,1814 mode,1815 renderExpirationTime,1816 null,1817 );1818 fallbackChildFragment.return = workInProgress;1819 primaryChildFragment.sibling = fallbackChildFragment;1820 fallbackChildFragment.effectTag |= Placement;1821 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1822 current,1823 workInProgress,1824 renderExpirationTime,1825 );1826 workInProgress.memoizedState = updateSuspenseState(1827 current.memoizedState,1828 renderExpirationTime,1829 );1830 workInProgress.child = primaryChildFragment;1831 // Skip the primary children, and continue working on the1832 // fallback children.1833 return fallbackChildFragment;1834 }1835 }1836 }1837 // The current tree already timed out. That means each child set is1838 // wrapped in a fragment fiber.1839 const currentPrimaryChildFragment: Fiber = (current.child: any);1840 const currentFallbackChildFragment: Fiber = (currentPrimaryChildFragment.sibling: any);1841 if (nextDidTimeout) {1842 // Still timed out. Reuse the current primary children by cloning1843 // its fragment. We're going to skip over these entirely.1844 const nextFallbackChildren = nextProps.fallback;1845 const primaryChildFragment = createWorkInProgress(1846 currentPrimaryChildFragment,1847 currentPrimaryChildFragment.pendingProps,1848 );1849 primaryChildFragment.return = workInProgress;1850 if ((workInProgress.mode & BlockingMode) === NoMode) {1851 // Outside of blocking mode, we commit the effects from the1852 // partially completed, timed-out tree, too.1853 const progressedState: SuspenseState = workInProgress.memoizedState;1854 const progressedPrimaryChild: Fiber | null =1855 progressedState !== null1856 ? (workInProgress.child: any).child1857 : (workInProgress.child: any);1858 if (progressedPrimaryChild !== currentPrimaryChildFragment.child) {1859 primaryChildFragment.child = progressedPrimaryChild;1860 let progressedChild = progressedPrimaryChild;1861 while (progressedChild !== null) {1862 progressedChild.return = primaryChildFragment;1863 progressedChild = progressedChild.sibling;1864 }1865 }1866 }1867 // Because primaryChildFragment is a new fiber that we're inserting as the1868 // parent of a new tree, we need to set its treeBaseDuration.1869 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1870 // treeBaseDuration is the sum of all the child tree base durations.1871 let treeBaseDuration = 0;1872 let hiddenChild = primaryChildFragment.child;1873 while (hiddenChild !== null) {1874 treeBaseDuration += hiddenChild.treeBaseDuration;1875 hiddenChild = hiddenChild.sibling;1876 }1877 primaryChildFragment.treeBaseDuration = treeBaseDuration;1878 }1879 // Clone the fallback child fragment, too. These we'll continue1880 // working on.1881 const fallbackChildFragment = createWorkInProgress(1882 currentFallbackChildFragment,1883 nextFallbackChildren,1884 );1885 fallbackChildFragment.return = workInProgress;1886 primaryChildFragment.sibling = fallbackChildFragment;1887 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1888 current,1889 workInProgress,1890 renderExpirationTime,1891 );1892 // Skip the primary children, and continue working on the1893 // fallback children.1894 workInProgress.memoizedState = updateSuspenseState(1895 current.memoizedState,1896 renderExpirationTime,1897 );1898 workInProgress.child = primaryChildFragment;1899 return fallbackChildFragment;1900 } else {1901 // No longer suspended. Switch back to showing the primary children,1902 // and remove the intermediate fragment fiber.1903 const nextPrimaryChildren = nextProps.children;1904 const currentPrimaryChild = currentPrimaryChildFragment.child;1905 const primaryChild = reconcileChildFibers(1906 workInProgress,1907 currentPrimaryChild,1908 nextPrimaryChildren,1909 renderExpirationTime,1910 );1911 // If this render doesn't suspend, we need to delete the fallback1912 // children. Wait until the complete phase, after we've confirmed the1913 // fallback is no longer needed.1914 // TODO: Would it be better to store the fallback fragment on1915 // the stateNode?1916 // Continue rendering the children, like we normally do.1917 workInProgress.memoizedState = null;1918 return (workInProgress.child = primaryChild);1919 }1920 } else {1921 // The current tree has not already timed out. That means the primary1922 // children are not wrapped in a fragment fiber.1923 const currentPrimaryChild = current.child;1924 if (nextDidTimeout) {1925 // Timed out. Wrap the children in a fragment fiber to keep them1926 // separate from the fallback children.1927 const nextFallbackChildren = nextProps.fallback;1928 const primaryChildFragment = createFiberFromFragment(1929 // It shouldn't matter what the pending props are because we aren't1930 // going to render this fragment.1931 null,1932 mode,1933 NoWork,1934 null,1935 );1936 primaryChildFragment.return = workInProgress;1937 primaryChildFragment.child = currentPrimaryChild;1938 if (currentPrimaryChild !== null) {1939 currentPrimaryChild.return = primaryChildFragment;1940 }1941 // Even though we're creating a new fiber, there are no new children,1942 // because we're reusing an already mounted tree. So we don't need to1943 // schedule a placement.1944 // primaryChildFragment.effectTag |= Placement;1945 if ((workInProgress.mode & BlockingMode) === NoMode) {1946 // Outside of blocking mode, we commit the effects from the1947 // partially completed, timed-out tree, too.1948 const progressedState: SuspenseState = workInProgress.memoizedState;1949 const progressedPrimaryChild: Fiber | null =1950 progressedState !== null1951 ? (workInProgress.child: any).child1952 : (workInProgress.child: any);1953 primaryChildFragment.child = progressedPrimaryChild;1954 let progressedChild = progressedPrimaryChild;1955 while (progressedChild !== null) {1956 progressedChild.return = primaryChildFragment;1957 progressedChild = progressedChild.sibling;1958 }1959 }1960 // Because primaryChildFragment is a new fiber that we're inserting as the1961 // parent of a new tree, we need to set its treeBaseDuration.1962 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {1963 // treeBaseDuration is the sum of all the child tree base durations.1964 let treeBaseDuration = 0;1965 let hiddenChild = primaryChildFragment.child;1966 while (hiddenChild !== null) {1967 treeBaseDuration += hiddenChild.treeBaseDuration;1968 hiddenChild = hiddenChild.sibling;1969 }1970 primaryChildFragment.treeBaseDuration = treeBaseDuration;1971 }1972 // Create a fragment from the fallback children, too.1973 const fallbackChildFragment = createFiberFromFragment(1974 nextFallbackChildren,1975 mode,1976 renderExpirationTime,1977 null,1978 );1979 fallbackChildFragment.return = workInProgress;1980 primaryChildFragment.sibling = fallbackChildFragment;1981 fallbackChildFragment.effectTag |= Placement;1982 primaryChildFragment.childExpirationTime = getRemainingWorkInPrimaryTree(1983 current,1984 workInProgress,1985 renderExpirationTime,1986 );1987 // Skip the primary children, and continue working on the1988 // fallback children.1989 workInProgress.memoizedState = mountSuspenseState(renderExpirationTime);1990 workInProgress.child = primaryChildFragment;1991 return fallbackChildFragment;1992 } else {1993 // Still haven't timed out. Continue rendering the children, like we1994 // normally do.1995 workInProgress.memoizedState = null;1996 const nextPrimaryChildren = nextProps.children;...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium } = require('playwright');2(async () => {3 const browser = await chromium.launch({4 });5 const context = await browser.newContext();6 const page = await context.newPage();7 console.log(await page._delegate.getRemainingWorkInPrimaryTree());8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { chromium, webkit, firefox } = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'google.png' });7 await browser.close();8})();9const { chromium, webkit, firefox } = require('playwright');10(async () => {11 const browser = await chromium.launch();12 const context = await browser.newContext();13 const page = await context.newPage();14 await page.screenshot({ path: 'google.png' });15 await browser.close();16})();17const { chromium, webkit, firefox } = require('playwright');18(async () => {19 const browser = await chromium.launch();20 const context = await browser.newContext();21 const page = await context.newPage();22 await page.screenshot({ path: 'google.png' });23 await browser.close();24})();25const { chromium, webkit, firefox } = require('playwright');26(async () => {27 const browser = await chromium.launch();28 const context = await browser.newContext();29 const page = await context.newPage();30 await page.screenshot({ path: 'google.png' });31 await browser.close();32})();33const { chromium, webkit, firefox } = require('playwright');34(async () => {35 const browser = await chromium.launch();36 const context = await browser.newContext();37 const page = await context.newPage();38 await page.screenshot({ path: 'google.png' });39 await browser.close();40})();41const { chromium, webkit, firefox } = require('

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.click('text=Get started');8 await page.click('text=Docs');9 await page.click('text=API');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/chromium/crBrowser.js');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await page.waitForSelector('text=Get started');7 await page.click('text=Get started');8 await page.waitForSelector('text=Create a test project');9 await page.click('text=Create a test project');10 await page.waitForSelector('text=Playwright is a Node.js library to automate');11 await browser.close();12})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await page.waitForSelector('.navbar__inner');7 console.log(getRemainingWorkInPrimaryTree());8 await browser.close();9})();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/chromium/crBrowser.js');2const browser = await chromium.launch();3const page = await browser.newPage();4await page.waitForSelector('text=Get started');5const remainingWork = await getRemainingWorkInPrimaryTree(page);6console.log(remainingWork);7await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/utils/progress');2const browser = await playwright.chromium.launch();3const context = await browser.newContext();4const page = await context.newPage();5await page.waitForSelector('.new-todo');6await page.type('.new-todo', 'Learn playwright');7await page.keyboard.press('Enter');8await page.type('.new-todo', 'Learn playwright internal API');9await page.keyboard.press('Enter');10await page.waitForSelector('.todo-list li:nth-child(2) .toggle');11await page.click('.todo-list li:nth-child(2) .toggle');12await page.waitForSelector('.todo-list li:nth-child(2).completed');13console.log(getRemainingWorkInPrimaryTree());14await browser.close();15const { getPendingTasks } = require('playwright/lib/utils/progress');16const browser = await playwright.chromium.launch();17const context = await browser.newContext();18const page = await context.newPage();19await page.waitForSelector('.new-todo');20await page.type('.new-todo', 'Learn playwright');21await page.keyboard.press('Enter');22await page.type('.new-todo', 'Learn playwright internal API');23await page.keyboard.press('Enter');24await page.waitForSelector('.todo-list li:nth-child(2) .toggle');25await page.click('.todo-list li:nth-child(2) .toggle');26await page.waitForSelector('.todo-list li:nth-child(2).completed');27console.log(getPendingTasks());28await browser.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');2const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');3const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');4const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');5const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');6const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');7const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');8const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');9const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/progress');

Full Screen

Using AI Code Generation

copy

Full Screen

1const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2module.exports = async function(context, commands) {3 await commands.measure.stop();4 await commands.measure.stop();5 await commands.measure.stop();6 await commands.measure.stop();7};8const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/supplements/recorder/recorderSupplement');9module.exports = async function(context, commands) {10 await commands.measure.stop();11 await commands.measure.stop();12 await commands.measure.stop();13 await commands.measure.stop();14};15const { getRemainingWorkInPrimaryTree } = require('playwright/lib/server/supplements/recorder/recorderSupplement');16module.exports = async function(context, commands) {17 await commands.measure.stop();18 await commands.measure.stop();19 await commands.measure.stop();20 await commands.measure.stop();21 await commands.measure.stop();22 await commands.measure.stop();23 await commands.measure.stop();24};25const { getRemainingWorkInPrimaryTree } = require

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful