From a1690090958a73f4122ef53ab64ec886e37045dd Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 4 Aug 2021 13:45:49 -0700 Subject: [PATCH] React Native sync for revisions 419cc9c...19092ac MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This sync includes the following changes: - **[19092ac8c](https://github.com/facebook/react/commit/19092ac8c )**: Re-add old Fabric Offscreen impl behind flag ([#22018](https://github.com/facebook/react/pull/22018)) //// - **[215db465a](https://github.com/facebook/react/commit/215db465a )**: [Fabric] Add `flex: 1` to Offscreen view container ([#22019](https://github.com/facebook/react/pull/22019)) //// - **[8a37b0ef3](https://github.com/facebook/react/commit/8a37b0ef3 )**: typos fixed ([#21955](https://github.com/facebook/react/pull/21955)) //// - **[e3049bb85](https://github.com/facebook/react/commit/e3049bb85 )**: DevTools scheduling profiler: Add React component measures ([#22013](https://github.com/facebook/react/pull/22013)) //// - **[27bf6f9a8](https://github.com/facebook/react/commit/27bf6f9a8 )**: Scheduling profiler UX changes ([#21990](https://github.com/facebook/react/pull/21990)) //// - **[f0d354efc](https://github.com/facebook/react/commit/f0d354efc )**: [Fabric] Fix reparenting bug in legacy Suspense mount ([#21995](https://github.com/facebook/react/pull/21995)) //// - **[34308b5ad](https://github.com/facebook/react/commit/34308b5ad )**: Tidy up early bailout logic at start of begin phase ([#21852](https://github.com/facebook/react/pull/21852)) //// - **[321087d13](https://github.com/facebook/react/commit/321087d13 )**: [Fizz] Don't add aborted segments to the completedSegments list ([#21976](https://github.com/facebook/react/pull/21976)) //// - **[4cc8ec64c](https://github.com/facebook/react/commit/4cc8ec64c )**: Separate unit tests for ReactFabricHostComponent ([#21969](https://github.com/facebook/react/pull/21969)) //// - **[d4d786493](https://github.com/facebook/react/commit/d4d786493 )**: Fix `ReactFabricHostComponent` methods if detached ([#21967](https://github.com/facebook/react/pull/21967)) //// - **[392253a77](https://github.com/facebook/react/commit/392253a77 )**: [Fabric] Use container node to toggle the visibility of Offscreen and Suspense trees ([#21960](https://github.com/facebook/react/pull/21960)) //// Changelog: [General][Changed] - React Native sync for revisions 419cc9c...19092ac jest_e2e[run_all_tests] Reviewed By: JoshuaGross Differential Revision: D30092460 fbshipit-source-id: 9f118db2419a9a5db26a9b873868f91ab88f2f89 --- BUCK | 1 + Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 6580 +++++++++-------- .../implementations/ReactFabric-prod.fb.js | 1959 ++--- .../ReactFabric-profiling.fb.js | 2207 +++--- .../ReactNativeRenderer-dev.fb.js | 6221 ++++++++-------- .../ReactNativeRenderer-prod.fb.js | 1219 ++- .../ReactNativeRenderer-profiling.fb.js | 2439 +++--- Libraries/Renderer/shims/ReactFabric.js | 4 +- Libraries/Renderer/shims/ReactFeatureFlags.js | 4 +- Libraries/Renderer/shims/ReactNative.js | 4 +- Libraries/Renderer/shims/ReactNativeTypes.js | 4 +- .../shims/ReactNativeViewConfigRegistry.js | 4 +- .../shims/createReactNativeComponentClass.js | 4 +- 14 files changed, 10689 insertions(+), 9963 deletions(-) diff --git a/BUCK b/BUCK index 7f0de5d009e6fb..acf57d1e6e3773 100644 --- a/BUCK +++ b/BUCK @@ -708,6 +708,7 @@ rn_library( "//xplat/js:node_modules__use_19subscription", "//xplat/js:node_modules__whatwg_19fetch", "//xplat/js/RKJSModules/Libraries/Polyfills:Polyfills", + "//xplat/js/RKJSModules/Libraries/React:React", "//xplat/js/RKJSModules/vendor/react:react", "//xplat/js/RKJSModules/vendor/react-test-renderer:react-test-renderer", "//xplat/js/RKJSModules/vendor/scheduler:scheduler", diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index cdf4b841f1a039..3da1c44603e605 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -419cc9c3799bc296c3c2a2c93880826aca680886 \ No newline at end of file +19092ac8c354b92c2e0e27b73f391571ad452505 \ No newline at end of file diff --git a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 06a99f732fee1b..fe5093e6cfaf0d 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7030f8cf60391b0a117fd83a00a5b3be>> + * @generated SignedSource<<6c8346987db638ec0cd71246cb829ef6>> */ 'use strict'; @@ -19,6 +19,7 @@ if (__DEV__) { var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var dynamicFlags = require("ReactNativeInternalFeatureFlags"); var Scheduler = require("scheduler"); var ReactSharedInternals = @@ -2839,7 +2840,11 @@ function getComponentNameFromFiber(fiber) { return null; } -// The rest of the flags are static for better dead code elimination. +// Re-export dynamic flags from the internal module. Intentionally using * +// the exports object every time a flag is read. + +var enablePersistentOffscreenHostContainer = + dynamicFlags.enablePersistentOffscreenHostContainer; // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableLazyElements = false; @@ -4871,17 +4876,25 @@ var ReactFabricHostComponent = /*#__PURE__*/ (function() { }; _proto.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + + if (stateNode != null) { + fabricMeasure( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } }; _proto.measureInWindow = function measureInWindow(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + + if (stateNode != null) { + fabricMeasureInWindow( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + } }; _proto.measureLayout = function measureLayout( @@ -4903,12 +4916,17 @@ var ReactFabricHostComponent = /*#__PURE__*/ (function() { return; } - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); + var toStateNode = this._internalInstanceHandle.stateNode; + var fromStateNode = relativeToNativeNode._internalInstanceHandle.stateNode; + + if (toStateNode != null && fromStateNode != null) { + fabricMeasureLayout( + toStateNode.node, + fromStateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } }; _proto.setNativeProps = function setNativeProps(nativeProps) { @@ -5001,7 +5019,8 @@ function getChildHostContext(parentHostContext, type, rootContainerInstance) { type === "RCTMultilineTextInputView" || // iOS type === "RCTSinglelineTextInputView" || // iOS type === "RCTText" || - type === "RCTVirtualText"; + type === "RCTVirtualText"; // TODO: If this is an offscreen host container, we should reuse the + // parent context. if (prevIsInAParentText !== isInAParentText) { return { @@ -5067,6 +5086,10 @@ function getCurrentEventPriority() { var scheduleTimeout = setTimeout; var cancelTimeout = clearTimeout; var noTimeout = -1; // ------------------- +// Persistence +// ------------------- + +var supportsPersistence = true; function cloneInstance( instance, updatePayload, @@ -5098,6 +5121,34 @@ function cloneInstance( node: clone, canonical: instance.canonical }; +} // TODO: These two methods should be replaced with `createOffscreenInstance` and +// `cloneOffscreenInstance`. I did it this way for now because the offscreen +// instance is stored on an extra HostComponent fiber instead of the +// OffscreenComponent fiber, and I didn't want to add an extra check to the +// generic HostComponent path. Instead we should use the OffscreenComponent +// fiber, but currently Fabric expects a 1:1 correspondence between Fabric +// instances and host fibers, so I'm leaving this optimization for later once +// we can confirm this won't break any downstream expectations. + +function getOffscreenContainerType() { + return "RCTView"; +} +function getOffscreenContainerProps(mode, children) { + if (mode === "hidden") { + return { + children: children, + style: { + display: "none" + } + }; + } else { + return { + children: children, + style: { + flex: 1 + } + }; + } } function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { var viewConfig = instance.canonical.viewConfig; @@ -5862,7 +5913,7 @@ var Passive$1 = /* */ 4; -var ReactVersion = "18.0.0-419cc9c37-20210726"; +var ReactVersion = "18.0.0-19092ac8c-20210803"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -12770,6 +12821,28 @@ function throwException( sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + if (enablePersistentOffscreenHostContainer) { + // Another legacy Suspense quirk. In persistent mode, if this is the + // initial mount, override the props of the host container to hide + // its contents. + var currentSuspenseBoundary = _workInProgress.alternate; + + if (currentSuspenseBoundary === null) { + var offscreenFiber = _workInProgress.child; + var offscreenContainer = offscreenFiber.child; + + if (offscreenContainer !== null) { + var children = offscreenContainer.memoizedProps.children; + var containerProps = getOffscreenContainerProps( + "hidden", + children + ); + offscreenContainer.pendingProps = containerProps; + offscreenContainer.memoizedProps = containerProps; + } + } + } + if (sourceFiber.tag === ClassComponent) { var _currentSourceFiber = sourceFiber.alternate; @@ -12834,7 +12907,9 @@ function throwException( // ensure that new initial loading states can commit as soon as possible. attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; + _workInProgress.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in + // the begin phase to prevent an early bailout. + _workInProgress.lanes = rootRenderLanes; return; } // This boundary already captured during this render. Continue to the next @@ -12909,3839 +12984,4018 @@ function throwException( } while (workInProgress !== null); } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; - -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; -} - -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - if (current === null) { - // If this is a fresh new component that hasn't been rendered yet, we - // won't update its child set by applying minimal side-effects. Instead, - // we will add them all to the child before it gets rendered. That means - // we can optimize this reconciliation pass by not tracking side-effects. - workInProgress.child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - // If the current child is the same as the work in progress, it means that - // we haven't yet started any work on these children. Therefore, we use - // the clone algorithm to create a copy of all the current children. - // If we had any progressed work already, that is invalid at this point so - // let's throw it out. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); - } +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes -) { - // This function is fork of reconcileChildren. It's used in cases where we - // want to reconcile without matching against the existing set. This has the - // effect of all current children being unmounted; even if the type and key - // are the same, the old child is unmounted and a new child is created. - // - // To do this, we're going to go through the reconcile algorithm twice. In - // the first pass, we schedule a deletion for all the current children by - // passing null. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. - - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); +function markRef(workInProgress) { + workInProgress.flags |= Ref; } -function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens after the first render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; +function hadNoMutationsEffects(current, completedWork) { + var didBailout = current !== null && current.child === completedWork.child; - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); - } - } + if (didBailout) { + return true; } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); - - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); + if ((completedWork.flags & ChildDeletion) !== NoFlags) { + return false; + } // TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties` + // then we only have to check the `completedWork.subtreeFlags`. - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + var child = completedWork.child; - try { - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); - } finally { - reenableLogs(); - } + while (child !== null) { + if ( + (child.flags & MutationMask) !== NoFlags || + (child.subtreeFlags & MutationMask) !== NoFlags + ) { + return false; } - setIsRendering(false); + child = child.sibling; } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + return true; } -function updateMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - if (current === null) { - var type = Component.type; - - if ( - isSimpleFunctionComponent(type) && - Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. - Component.defaultProps === undefined - ) { - var resolvedType = type; +var appendAllChildren; +var updateHostContainer; +var updateHostComponent; +var updateHostText; - { - resolvedType = resolveFunctionForHotReloading(type); - } // If this is a plain function component without default props, - // and with only the default shallow comparison, we upgrade it - // to a SimpleMemoComponent to allow fast path updates. +{ + // Persistent host tree mode + appendAllChildren = function( + parent, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; - { - validateFunctionComponentInDev(workInProgress, type); - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - { - var innerPropTypes = type.propTypes; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - if (innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(type) - ); + appendInitialChild(parent, _instance); + } else if (node.tag === HostPortal); + else if (node.tag === OffscreenComponent && node.memoizedState !== null) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = node.child; + + if (child !== null) { + child.return = node; + } + + if (enablePersistentOffscreenHostContainer) { + appendAllChildren(parent, node, false, false); + } else { + appendAllChildren(parent, node, true, true); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } // $FlowFixMe This is correct but Flow is confused by the labeled break. + + node = node; + + if (node === workInProgress) { + return; } - } - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + node = node.return; + } - if (_innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - _innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(_type) - ); + node.sibling.return = node.return; + node = node.sibling; } - } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - var currentChild = current.child; // This is always exactly one child + var appendAllChildrenToContainer = function( + containerChildSet, + workInProgress, + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; - if (!includesSomeLane(updateLanes, renderLanes)) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } - } // React DevTools reads this flag. + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance2 = node.stateNode; - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance2 = cloneHiddenTextInstance(); + } -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens when the inner render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var outerMemoType = workInProgress.elementType; + appendChildToContainerChildSet(containerChildSet, _instance2); + } else if (node.tag === HostPortal); + else if (node.tag === OffscreenComponent && node.memoizedState !== null) { + // The children in this boundary are hidden. Toggle their visibility + // before appending. + var child = node.child; - if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { - // We warn when you define propTypes on lazy() - // so let's just skip over it to find memo() outer wrapper. - // Inner props for memo are validated later. - var lazyComponent = outerMemoType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (child !== null) { + child.return = node; + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + if (enablePersistentOffscreenHostContainer) { + appendAllChildrenToContainer(containerChildSet, node, false, false); + } else { + appendAllChildrenToContainer(containerChildSet, node, true, true); + } + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } // $FlowFixMe This is correct but Flow is confused by the labeled break. - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + node = node; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentNameFromType(outerMemoType) - ); + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } - } + }; - if (current !== null) { - var prevProps = current.memoizedProps; + updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; + if (childrenUnchanged); + else { + var container = portalOrRoot.containerInfo; + var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. - if (!includesSomeLane(renderLanes, updateLanes)) { - // The pending lanes were cleared at the beginning of beginWork. We're - // about to bail out, but there might be other lanes that weren't - // included in the current render. Usually, the priority level of the - // remaining updates is accumulated during the evaluation of the - // component (i.e. when processing the update queue). But since since - // we're bailing out early *without* evaluating the component, we need - // to account for it here, too. Reset to the value of the current fiber. - // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, - // because a MemoComponent fiber does not have hooks or an update queue; - // rather, it wraps around an inner component, which may or may not - // contains hooks. - // TODO: Move the reset at in beginWork out of the common path so that - // this is no longer necessary. - workInProgress.lanes = current.lanes; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); } - } + }; - return updateFunctionComponent( + updateHostComponent = function( current, workInProgress, - Component, - nextProps, - renderLanes - ); -} - -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the - // previous render. We will push this to the cache pool context so that we can - // resume in-flight requests. + type, + newProps, + rootContainerInstance + ) { + var currentInstance = current.stateNode; + var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. + // This guarantees that we can reuse all of them. - var spawnedCachePool = null; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" - ) { - // Rendering a hidden tree. - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - var nextState = { - baseLanes: NoLanes, - cachePool: null - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - // We're hidden, and we're not rendering at Offscreen. We will bail out - // and resume this tree later. - var nextBaseLanes; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - if (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps ); - var _nextState = { - baseLanes: nextBaseLanes, - cachePool: spawnedCachePool - }; - workInProgress.memoizedState = _nextState; - workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. - - pushRenderLanes(workInProgress, nextBaseLanes); - - return null; - } else { - var _nextState2 = { - baseLanes: NoLanes, - cachePool: null - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + } - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; } - } else { - // Rendering a visible tree. - var _subtreeRenderLanes; - if (prevState !== null) { - // We're going from hidden -> visible. - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - workInProgress.memoizedState = null; + workInProgress.stateNode = newInstance; + + if (childrenUnchanged) { + // If there are no other effects in this tree, we need to flag this node as having one. + // Even though we're not going to use it for anything. + // Otherwise parents won't know that there are new children to propagate upwards. + markUpdate(workInProgress); } else { - // We weren't previously hidden, and we still aren't, so there's nothing - // special to do. Need to push to the stack regardless, though, to avoid - // a push/pop misalignment. - _subtreeRenderLanes = renderLanes; + // If children might have changed, we have to add them all to the set. + appendAllChildren(newInstance, workInProgress, false, false); } + }; - pushRenderLanes(workInProgress, _subtreeRenderLanes); - } + updateHostText = function(current, workInProgress, oldText, newText) { + if (oldText !== newText) { + // If the text content differs, we'll create a new text instance for it. + var rootContainerInstance = getRootHostContainer(); + var currentHostContext = getHostContext(); + workInProgress.stateNode = createTextInstance( + newText, + rootContainerInstance, + currentHostContext, + workInProgress + ); // We'll have to mark it as having an effect, even though we won't use the effect for anything. + // This lets the parents know that at least one of their children has changed. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} // Note: These happen to have identical begin phases, for now. We shouldn't hold -// ourselves to this constraint, though. If the behavior diverges, we should -// fork the function. + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} -var updateLegacyHiddenComponent = updateOffscreenComponent; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. -function updateProfiler(current, workInProgress, renderLanes) { - { - workInProgress.flags |= Update; + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; + } - { - // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + break; } - } - - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} -function markRef(current, workInProgress) { - var ref = workInProgress.ref; + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } -} + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } -function updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; } + + break; } } +} - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); - - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) ); - } finally { - reenableLogs(); - } - } + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. - setIsRendering(false); - } + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. -function updateClassComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - { - // This is used by DevTools to force a boundary to error. - switch (shouldError(workInProgress)) { - case false: { - var _instance = workInProgress.stateNode; - var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. - // Is there a better way to do this? + _child.return = completedWork; + _child = _child.sibling; + } + } - var tempInstance = new ctor( - workInProgress.memoizedProps, - _instance.context - ); - var state = tempInstance.state; + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; - _instance.updater.enqueueSetState(_instance, state, null); + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. - break; + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; } - case true: { - workInProgress.flags |= DidCapture; - workInProgress.flags |= ShouldCapture; - var error$1 = new Error("Simulated error coming from DevTools"); - var lane = pickArbitraryLane(renderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; - var update = createClassErrorUpdate( - workInProgress, - createCapturedValue(error$1, workInProgress), - lane - ); - enqueueCapturedUpdate(workInProgress, update); - break; - } - } + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); + _child3.return = completedWork; + _child3 = _child3.sibling; } } - } // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. - var hasContext; - - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + completedWork.subtreeFlags |= subtreeFlags; } - prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; - - if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + completedWork.childLanes = newChildLanes; + return didBailout; +} - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. +function completeSuspendedOffscreenHostContainer(current, workInProgress) { + // This is a fork of the complete phase for HostComponent. We use it when + // a suspense tree is in its fallback state, because in that case the primary + // tree that includes the offscreen boundary is skipped over without a + // regular complete phase. + // + // We can optimize this path further by inlining the update logic for + // offscreen instances specifically, i.e. skipping the `prepareUpdate` call. + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + var newProps = workInProgress.memoizedProps; - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( + if (current !== null) { + updateHostComponent( + current, workInProgress, - Component, - nextProps, - renderLanes + type, + newProps, + rootContainerInstance ); } else { - shouldUpdate = updateClassInstance( - current, - workInProgress, - Component, - nextProps, - renderLanes + var currentHostContext = getHostContext(); + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef(workInProgress); + } } - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + bubbleProperties(workInProgress); +} - { - var inst = workInProgress.stateNode; +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { - error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentNameFromFiber(workInProgress) || "a component" - ); + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; + + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + popContext(workInProgress); } - didWarnAboutReassigningProps = true; + bubbleProperties(workInProgress); + return null; } - } - return nextUnitOfWork; -} + case HostRoot: { + var fiberRoot = workInProgress.stateNode; -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes -) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } - - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - var instance = workInProgress.stateNode; // Rerender + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else if (!fiberRoot.hydrate) { + // Schedule an effect to clear this container at the start of the next commit. + // This handles the case of React rendering into a container with previous children. + // It's also safe to do for updates too, because current.child would only be null + // if the previous render was null (so the the container would already be empty). + workInProgress.flags |= Snapshot; + } + } - { - stopProfilerTimerIfRunning(); + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; - try { - instance.render(); - } finally { - reenableLogs(); + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef(workInProgress); } - } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. - setIsRendering(false); - } - } // React DevTools reads this flag. + bubbleProperties(workInProgress); + return null; + } - workInProgress.flags |= PerformedWork; + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. - if (current !== null && didCaptureError) { - // If we're recovering from an error, reconcile without reusing any of - // the existing children. Conceptually, the normal children and the children - // that are shown on error are two different sets, so we shouldn't reuse - // normal children even if their identities match. - forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + var _wasHydrated = popHydrationState(); - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); - } + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef(workInProgress); + } + } - return workInProgress.child; -} + bubbleProperties(workInProgress); + return null; + } -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; + case HostText: { + var newText = newProps; - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. - pushHostContainer(workInProgress, root.containerInfo); -} + updateHostText(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + var _rootContainerInstance = getRootHostContainer(); - if (!(current !== null && updateQueue !== null)) { - throw Error( - "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." - ); - } + var _currentHostContext = getHostContext(); - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState.element; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; - var root = workInProgress.stateNode; - // being called "element". + var _wasHydrated2 = popHydrationState(); - var nextChildren = nextState.element; + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + bubbleProperties(workInProgress); + return null; + } - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - while (node) { - // Mark each child as hydrating. This is a fast path to know whether this - // tree is part of a hydrating tree. This is used to determine if a child - // node has fully mounted yet, and for scheduling event replaying. - // Conceptually this is similar to Placement in that a new subtree is - // inserted into the React tree here. It just happens to not need DOM - // mutations because it already exists. - node.flags = (node.flags & ~Placement) | Hydrating; - node = node.sibling; - } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - return workInProgress.child; -} + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); + return workInProgress; + } - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - if (prevProps !== null && shouldSetTextContent()) { - // If we're switching from a direct text child to a normal child, or to - // empty, we need to schedule the text content to be reset. - workInProgress.flags |= ContentReset; - } - - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (current === null); + else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } // If the suspended state of the boundary changes, we need to schedule + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. -function updateHostText(current, workInProgress) { - // immediately after. + if (nextDidTimeout && !prevDidTimeout) { + var offscreenFiber = workInProgress.child; + offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. - return null; -} + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = + current === null && + workInProgress.memoizedProps.unstable_avoidThisFallback !== true; -function mountLazyComponent( - _current, - workInProgress, - elementType, - updateLanes, - renderLanes -) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } + } - workInProgress.flags |= Placement; - } + var wakeables = workInProgress.updateQueue; - var props = workInProgress.pendingProps; - var lazyComponent = elementType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - var Component = init(payload); // Store the unwrapped component in the type. + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; + } - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + bubbleProperties(workInProgress); - switch (resolvedTag) { - case FunctionComponent: { { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment2 = workInProgress.child; + + if (_primaryChildFragment2 !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } } - child = updateFunctionComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; + return null; } - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); } - child = updateClassComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; - } + bubbleProperties(workInProgress); + return null; - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; + + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; + + if (isContextProvider(_Component)) { + popContext(workInProgress); } - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; + bubbleProperties(workInProgress); + return null; } - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentNameFromType(Component) - ); - } - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; } - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; - } - } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - var hint = ""; + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.flags & DidCapture) === NoFlags); - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. + if (!cannotBeSuspended) { + var row = workInProgress.child; - { - throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint - ); - } -} + while (row !== null) { + var suspended = findFirstSuspended(row); -function mountIncompleteClassComponent( - _current, - workInProgress, - Component, - nextProps, - renderLanes -) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thennables. Instead, we'll transfer its thennables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + var newThennables = suspended.updateQueue; - workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. - var hasContext; + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); -} + return workInProgress.child; + } -function mountIndeterminateComponent( - _current, - workInProgress, - Component, - renderLanes -) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + row = row.sibling; + } + } - workInProgress.flags |= Placement; - } + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. - var props = workInProgress.pendingProps; - var context; + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. - prepareToReadContext(workInProgress, renderLanes); - var value; + var _newThennables = _suspended.updateQueue; - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentNameFromType(Component) || "Unknown"; + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } - if (!didWarnAboutBadClass[componentName]) { - error( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + - "This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ); + cutOffTailIfNeeded(renderState, true); // This might have been modified. - didWarnAboutBadClass[componentName] = true; - } - } + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. - if (workInProgress.mode & StrictLegacyMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + workInProgress.lanes = SomeRetryLane; + } + } - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - setIsRendering(false); - } // React DevTools reads this flag. + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; - workInProgress.flags |= PerformedWork; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - { - // Support for module components is deprecated and is removed behind a flag. - // Whether or not it would crash later, we want to show a good message in DEV first. - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - var _componentName = getComponentNameFromType(Component) || "Unknown"; + renderState.last = renderedTail; + } + } - if (!didWarnAboutModulePatternComponent[_componentName]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName, - _componentName, - _componentName - ); + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. - didWarnAboutModulePatternComponent[_componentName] = true; + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } + + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. + + return next; } + + bubbleProperties(workInProgress); + return null; } - } - if ( - // Run these checks in production only if the flag is off. - // Eventually we'll delete this branch altogether. - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName2 = getComponentNameFromType(Component) || "Unknown"; + case ScopeComponent: { + break; + } - if (!didWarnAboutModulePatternComponent[_componentName2]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName2, - _componentName2, - _componentName2 - ); + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - didWarnAboutModulePatternComponent[_componentName2] = true; + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" && // LegacyHidden doesn't do any hiding — it only pre-renders. + workInProgress.tag !== LegacyHiddenComponent + ) { + workInProgress.flags |= Visibility; + } } - } // Proceed under the assumption that this is a class instance - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { + bubbleProperties(workInProgress); + } + } - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + return null; + } + } - var hasContext = false; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) { + // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers( workInProgress, - Component, - true, - hasContext, + null, + nextChildren, renderLanes ); } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; - - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } - } - } - - reconcileChildren(null, workInProgress, value, renderLanes); + // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); + } +} - { - validateFunctionComponentInDev(workInProgress, Component); - } +function forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes +) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes + ); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. - return workInProgress.child; - } + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); } -function validateFunctionComponentInDev(workInProgress, Component) { +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) ); } } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - var warningKey = ownerName || ""; - var debugSource = workInProgress._debugSource; + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes ); + } finally { + reenableLogs(); } } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentNameFromType(Component) || "Unknown"; + setIsRendering(false); + } - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if (current === null) { + var type = Component.type; if ( - typeof Component.contextType === "object" && - Component.contextType !== null + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined ) { - var _componentName4 = getComponentNameFromType(Component) || "Unknown"; + var resolvedType = type; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 - ); + { + resolvedType = resolveFunctionForHotReloading(type); + } // If this is a plain function component without default props, + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + renderLanes + ); + } + + { + var innerPropTypes = type.propTypes; + + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(type) + ); } } + + var child = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; } -} -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes, - cachePool: getSuspendedCachePool() - }; -} + if (_innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + _innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(_type) + ); + } + } -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - var cachePool = null; + var currentChild = current.child; // This is always exactly one child - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), - cachePool: cachePool - }; -} // TODO: Probably should inline this back + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); -function shouldRemainOnFallback( - suspenseContext, + if (!hasScheduledUpdateOrContext) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison + + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; + + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} + +function updateSimpleMemoComponent( current, workInProgress, + Component, + nextProps, renderLanes ) { - // If we're already showing a fallback, there are cases where we need to - // remain on that fallback regardless of whether the content has resolved. - // For example, SuspenseList coordinates when nested content appears. - if (current !== null) { - var suspenseState = current.memoizedState; - - if (suspenseState === null) { - // Currently showing content. Don't hide it, even if ForceSuspenseFallack - // is true. More precise name might be "ForceRemainSuspenseFallback". - // Note: This is a factoring smell. Can't remain on a fallback if there's - // no fallback to remain on. - return false; - } - } // Not currently showing content. Consult the Suspense context. + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens when the inner render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); -} + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + var outerPropTypes = outerMemoType && outerMemoType.propTypes; - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentNameFromType(outerMemoType) + ); + } + } } } - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + if (current !== null) { + var prevProps = current.memoizedProps; - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - showFallback = true; - workInProgress.flags &= ~DidCapture; - } else { - // Attempting the main content - if (current === null || current.memoizedState !== null) { - // This is a new mount or this boundary is already showing a fallback state. - // Mark this subtree context as having at least one invisible parent that could - // handle the fallback state. - // Avoided boundaries are not considered since they cannot handle preferred fallback states. - if (nextProps.unstable_avoidThisFallback !== true) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; + + if (!checkScheduledUpdateOrContext(current, renderLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumulated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; } } } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense - // boundary's children. This involves some custom reconcilation logic. Two - // main reasons this is so complicated. - // - // First, Legacy Mode has different semantics for backwards compatibility. The - // primary tree will commit in an inconsistent state, so when we do the - // second pass to render the fallback, we do some exceedingly, uh, clever - // hacks to make that not totally break. Like transferring effects and - // deletions from hidden tree. In Concurrent Mode, it's much simpler, - // because we bailout on the primary tree completely and leave it in its old - // state, no effects. Same as what we do for Offscreen (except that - // Offscreen doesn't have the first render pass). - // - // Second is hydration. During hydration, the Suspense fiber has a slightly - // different layout, where the child points to a dehydrated fragment, which - // contains the DOM rendered by the server. - // - // Third, even if you set all that aside, Suspense is like error boundaries in - // that we first we try to render one tree, and if that fails, we render again - // and switch to a different tree. Like a try/catch block. So we have to track - // which branch we're currently rendering. Ideally we would model this using - // a stack. + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} - if (current === null) { - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. - if (showFallback) { - var fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - var primaryChildFragment = workInProgress.child; - primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return fallbackFragment; - } else if (typeof nextProps.unstable_expectedLoadTime === "number") { - // This is a CPU-bound tree. Skip this tree and show a placeholder to - // unblock the surrounding content. Then immediately retry after the - // initial commit. - var _fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); + var spawnedCachePool = null; - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; + + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. + + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane ); - workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to - // get it started back up to attempt the next item. While in terms of - // priority this work has the same priority as this current render, it's - // not part of the same transition once the transition has committed. If - // it's sync, we still want to yield so that it can be painted. - // Conceptually, this is really the same as pinging. We can use any - // RetryLane even if it's the one currently rendering since we're leaving - // it behind on this node. + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. - workInProgress.lanes = SomeRetryLane; - return _fallbackFragment; + pushRenderLanes(workInProgress, nextBaseLanes); + + return null; } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); } } else { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; + // Rendering a visible tree. + var _subtreeRenderLanes; if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; - - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes - ); - - var _primaryChildFragment3 = workInProgress.child; - var prevOffscreenState = current.child.memoizedState; - _primaryChildFragment3.memoizedState = - prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); - _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment; - } else { - var _nextPrimaryChildren3 = nextProps.children; - - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); - workInProgress.memoizedState = null; - return _primaryChildFragment4; - } + workInProgress.memoizedState = null; } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; - - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); - - var _primaryChildFragment5 = workInProgress.child; - var _prevOffscreenState = current.child.memoizedState; - _primaryChildFragment5.memoizedState = - _prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); - _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); // Skip the primary children, and continue working on the - // fallback children. - - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; - - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); - - workInProgress.memoizedState = null; - return _primaryChildFragment6; - } + // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; } + + pushRenderLanes(workInProgress, _subtreeRenderLanes); + } + + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // TODO: Optimize this to use the OffscreenComponent fiber instead of + // an extra HostComponent fiber. Need to make sure this doesn't break Fabric + // or some other infra that expects a HostComponent. + var isHidden = + nextProps.mode === "hidden" && + workInProgress.tag !== LegacyHiddenComponent; + var offscreenContainer = reconcileOffscreenHostContainer( + current, + workInProgress, + isHidden, + nextChildren, + renderLanes + ); + return offscreenContainer; + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } } -function mountSuspensePrimaryChildren( - workInProgress, - primaryChildren, +function reconcileOffscreenHostContainer( + currentOffscreen, + offscreen, + isHidden, + children, renderLanes ) { - var mode = workInProgress.mode; - var primaryChildProps = { - mode: "visible", - children: primaryChildren - }; - var primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - renderLanes, - null + var containerProps = getOffscreenContainerProps( + isHidden ? "hidden" : "visible", + children ); - primaryChildFragment.return = workInProgress; - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} - -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; - - if ( - (mode & ConcurrentMode) === NoMode && - progressedPrimaryFragment !== null - ) { - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; - - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = 0; - primaryChildFragment.treeBaseDuration = 0; - } + var hostContainer; - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, + if (currentOffscreen === null) { + hostContainer = createOffscreenHostContainerFiber( + containerProps, + offscreen.mode, renderLanes, null ); } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var currentHostContainer = currentOffscreen.child; + + if (currentHostContainer === null) { + hostContainer = createOffscreenHostContainerFiber( + containerProps, + offscreen.mode, + renderLanes, + null + ); + hostContainer.flags |= Placement; + } else { + hostContainer = createWorkInProgress( + currentHostContainer, + containerProps + ); + } } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; + hostContainer.return = offscreen; + offscreen.child = hostContainer; + return hostContainer; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold +// ourselves to this constraint, though. If the behavior diverges, we should +// fork the function. + +var updateLegacyHiddenComponent = updateOffscreenComponent; + +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function createWorkInProgressOffscreenFiber(current, offscreenProps) { - // The props argument to `createWorkInProgress` is `any` typed, so we use this - // wrapper function to constrain it. - return createWorkInProgress(current, offscreenProps); +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, +function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; + { - mode: "visible", - children: primaryChildren + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } - ); - - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - var deletions = workInProgress.deletions; +function markRef$1(current, workInProgress) { + var ref = workInProgress.ref; - if (deletions === null) { - workInProgress.deletions = [currentFallbackChildFragment]; - workInProgress.flags |= ChildDeletion; - } else { - deletions.push(currentFallbackChildFragment); - } + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; } - - workInProgress.child = primaryChildFragment; - return primaryChildFragment; } -function updateSuspenseFallbackChildren( +function updateFunctionComponent( current, workInProgress, - primaryChildren, - fallbackChildren, + Component, + nextProps, renderLanes ) { - var mode = workInProgress.mode; - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was - // already cloned. In legacy mode, the only case where this isn't true is - // when DevTools forces us to display a fallback; we skip the first render - // pass entirely and go straight to rendering the fallback. (In Concurrent - // Mode, SuspenseList can also trigger this scenario, but this is a legacy- - // only codepath.) - workInProgress.child !== currentPrimaryChildFragment - ) { - var progressedPrimaryFragment = workInProgress.child; - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; - - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration; - primaryChildFragment.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. - - workInProgress.deletions = null; - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); // Since we're reusing a current tree, we need to reuse the flags, too. - // (We don't do this in legacy mode, because in legacy mode we don't re-use - // the current tree; see previous branch.) + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - primaryChildFragment.subtreeFlags = - currentPrimaryChildFragment.subtreeFlags & StaticMask; + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) + ); + } + } } - var fallbackChildFragment; - - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - ); - } else { - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); // Needs a placement effect because the parent (the Suspense boundary) already - // mounted but this is a new fiber. + var context; - fallbackChildFragment.flags |= Placement; + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); } - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + try { + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); } - scheduleWorkOnParentPath(fiber.return, renderLanes); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function propagateSuspenseContextChange( +function updateClassComponent( + current, workInProgress, - firstChild, + Component, + nextProps, renderLanes ) { - // Mark any Suspense boundaries with fallbacks as having work to do. - // If they were previously forced into fallbacks, they may now be able - // to unblock. - var node = firstChild; + { + // This is used by DevTools to force a boundary to error. + switch (shouldError(workInProgress)) { + case false: { + var _instance = workInProgress.stateNode; + var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. + // Is there a better way to do this? - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + var tempInstance = new ctor( + workInProgress.memoizedProps, + _instance.context + ); + var state = tempInstance.state; - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + _instance.updater.enqueueSetState(_instance, state, null); + + break; } - } else if (node.tag === SuspenseListComponent) { - // If the tail is hidden there might not be an Suspense boundaries - // to schedule work on. In this case we have to schedule it on the - // list itself. - // We don't have to traverse to the children of the list since - // the list will propagate the change when it rerenders. - scheduleWorkOnFiber(node, renderLanes); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) { - return; - } + case true: { + workInProgress.flags |= DidCapture; + workInProgress.flags |= ShouldCapture; + var error$1 = new Error("Simulated error coming from DevTools"); + var lane = pickArbitraryLane(renderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + var update = createClassErrorUpdate( + workInProgress, + createCapturedValue(error$1, workInProgress), + lane + ); + enqueueCapturedUpdate(workInProgress, update); + break; } - - node = node.return; } - node.sibling.return = node.return; - node = node.sibling; - } -} - -function findLastContentRow(firstChild) { - // This is going to find the last row among these children that is already - // showing content on the screen, as opposed to being in fallback state or - // new. If a row has multiple Suspense boundaries, any of them being in the - // fallback state, counts as the whole row being in a fallback state. - // Note that the "rows" will be workInProgress, but any nested children - // will still be current since we haven't rendered them yet. The mounted - // order may not be the same as the new order. We use the new order. - var row = firstChild; - var lastContentRow = null; - - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) + ); + } } + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - row = row.sibling; - } - - return lastContentRow; -} - -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; - - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + var hasContext; - break; - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - case "forward": - case "backward": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - break; - } + if (instance === null) { + if (current !== null) { + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already + // committed. Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. - break; - } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - } + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderLanes + ); + } else { + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode - ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; + { + var inst = workInProgress.stateNode; + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentNameFromFiber(workInProgress) || "a component" ); } + + didWarnAboutReassigningProps = true; } } -} - -function validateSuspenseListNestedChild(childSlot, index) { - { - var isAnArray = isArray(childSlot); - var isIterable = - !isAnArray && typeof getIteratorFn(childSlot) === "function"; - if (isAnArray || isIterable) { - var type = isAnArray ? "array" : "iterable"; + return nextUnitOfWork; +} - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type - ); +function finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes +) { + // Refs should update even if shouldComponentUpdate returns false + markRef$1(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - return false; + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); } + + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - return true; -} + var instance = workInProgress.stateNode; // Rerender -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; - } - } - } else { - var iteratorFn = getIteratorFn(children); + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - _i++; - } - } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); + try { + instance.render(); + } finally { + reenableLogs(); } } + + setIsRendering(false); } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. + + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } + + return workInProgress.child; } -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode -) { - var renderState = workInProgress.memoizedState; +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }; - } else { - // We can reuse the existing object from previous renders. - renderState.isBackwards = isBackwards; - renderState.rendering = null; - renderState.renderingStartTime = 0; - renderState.last = lastContentRow; - renderState.tail = tail; - renderState.tailMode = tailMode; + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } + + pushHostContainer(workInProgress, root.containerInfo); +} + +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; + + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." + ); } -} // This can end up rendering this component multiple passes. -// The first pass splits the children fibers into two sets. A head and tail. -// We first render the head. If anything is in fallback state, we do another -// pass through beginWork to rerender all children (including the tail) with -// the force suspend context. If the first render didn't have anything in -// in fallback state. Then we render each row in the tail one-by-one. -// That happens in the completeWork phase without going back to beginWork. -function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps; - var revealOrder = nextProps.revealOrder; - var tailMode = nextProps.tail; - var newChildren = nextProps.children; - validateRevealOrder(revealOrder); - validateTailOptions(tailMode, revealOrder); - validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderLanes); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback + var nextChildren = nextState.element; + + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + workInProgress.child = child; + var node = child; - if (didSuspendBefore) { - // If we previously forced a fallback, we need to schedule work - // on any nested boundaries to let them know to try to render - // again. This is the same as context updating. - propagateSuspenseContextChange( - workInProgress, - workInProgress.child, - renderLanes - ); + while (node) { + // Mark each child as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + node.flags = (node.flags & ~Placement) | Hydrating; + node = node.sibling; } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } + + return workInProgress.child; +} - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); +function updateHostComponent$1(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); + + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; + + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; } - pushSuspenseContext(workInProgress, suspenseContext); + markRef$1(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy mode, SuspenseList doesn't work so we just - // use make it a noop by treating it as the default revealOrder. - workInProgress.memoizedState = null; - } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; +function updateHostText$1(current, workInProgress) { + // immediately after. - if (lastContentRow === null) { - // The whole list is part of the tail. - // TODO: We could fast path by just rendering the tail now. - tail = workInProgress.child; - workInProgress.child = null; - } else { - // Disconnect the tail rows after the content row. - // We're going to render them separately later. - tail = lastContentRow.sibling; - lastContentRow.sibling = null; - } + return null; +} - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode - ); - break; - } +function mountLazyComponent( + _current, + workInProgress, + elementType, + renderLanes +) { + if (_current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; + workInProgress.flags |= Placement; + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component ); - break; } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - break; } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentNameFromType(Component) + ); + } + } } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + renderLanes + ); + return child; } } - return workInProgress.child; -} + var hint = ""; -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + { + if ( + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE + ) { + hint = " Did you wrap a component in React.lazy() more than once?"; + } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. - if (current === null) { - // Portals are special because we don't append the children during mount - // but at commit. Therefore we need to track insertions which the normal - // flow doesn't do during mount. This doesn't happen at the root because - // the root always starts with a "current" with a null child. - // TODO: Consider unifying this with how the root works. - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); } - - return workInProgress.child; } -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - -function updateContextProvider(current, workInProgress, renderLanes) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; +function mountIncompleteClassComponent( + _current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if (_current !== null) { + // An incomplete component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } - } + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - var providerPropTypes = workInProgress.type.propTypes; + var hasContext; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - pushProvider(workInProgress, context, newValue); + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} - { - if (oldProps !== null) { - var oldValue = oldProps.value; +function mountIndeterminateComponent( + _current, + workInProgress, + Component, + renderLanes +) { + if (_current !== null) { + // An indeterminate component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - if (objectIs(oldValue, newValue)) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, renderLanes); - } - } + workInProgress.flags |= Placement; } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + var props = workInProgress.pendingProps; + var context; -var hasWarnedAboutUsingContextAsConsumer = false; + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } -function updateContextConsumer(current, workInProgress, renderLanes) { - var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In - // DEV mode, we create a separate object for Context.Consumer that acts - // like a proxy to Context. This proxy object adds unnecessary code in PROD - // so we use the old behaviour (Context.Consumer references Context) to - // reduce size and overhead. The separate object references context via - // a property called "_context", which also gives us the ability to check - // in DEV mode if this property exists or not and warn if it does not. + prepareToReadContext(workInProgress, renderLanes); + var value; { - if (context._context === undefined) { - // This may be because it's a Context (rather than a Consumer). - // Or it may be because it's older React where they're the same thing. - // We only want to warn if we're sure it's a new React. - if (context !== context.Consumer) { - if (!hasWarnedAboutUsingContextAsConsumer) { - hasWarnedAboutUsingContextAsConsumer = true; + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentNameFromType(Component) || "Unknown"; - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName + ); + + didWarnAboutBadClass[componentName] = true; } - } else { - context = context._context; } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; - - { - if (typeof render !== "function") { - error( - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); } - } - - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context); - var newChildren; - { - ReactCurrentOwner$1.current = workInProgress; setIsRendering(true); - newChildren = render(newValue); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); setIsRendering(false); - } // React DevTools reads this flag. + } workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + { + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = getComponentNameFromType(Component) || "Unknown"; -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + if (!didWarnAboutModulePatternComponent[_componentName]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName + ); - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + didWarnAboutModulePatternComponent[_componentName] = true; + } + } } - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - - if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { - // The children don't have any work either. We can skip them. - // TODO: Once we add back resuming, we should check if the children are - // a work-in-progress set. If so, we need to transfer their effects. + if ( + // Run these checks in production only if the flag is off. + // Eventually we'll delete this branch altogether. + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { { - return null; - } - } // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. + var _componentName2 = getComponentNameFromType(Component) || "Unknown"; - cloneChildFibers(current, workInProgress); - return workInProgress.child; -} + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + var hasContext = false; - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); } else { - var prevSibling = returnFiber.child; + hasContext = false; + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + { + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); + try { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + } finally { + reenableLogs(); } } + } - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. - - var deletions = returnFiber.deletions; + reconcileChildren(null, workInProgress, value, renderLanes); - if (deletions === null) { - returnFiber.deletions = [current]; - returnFiber.flags |= ChildDeletion; - } else { - deletions.push(current); + { + validateFunctionComponentInDev(workInProgress, Component); } - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - - return newWorkInProgress; + return workInProgress.child; } } -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; - +function validateFunctionComponentInDev(workInProgress, Component) { { - if (workInProgress._debugNeedsRemount && current !== null) { - // This will restart the begin phase with a new fiber. - return remountFiber( - current, - workInProgress, - createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ) - ); + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } } - } - - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; - - if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type - ) { - // If props or context changed, mark the fiber as having performed work. - // This may be unset if the props are determined to be equal later (memo). - didReceiveUpdate = true; - } else if (!includesSomeLane(renderLanes, updateLanes)) { - didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering - // the begin phase. There's still some bookkeeping we that needs to be done - // in this optimized path, mostly pushing stuff onto the stack. - - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; - case HostComponent: - pushHostContext(workInProgress); - break; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - case ClassComponent: { - var Component = workInProgress.type; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + var warningKey = ownerName || ""; + var debugSource = workInProgress._debugSource; - break; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - pushProvider(workInProgress, context, newValue); - break; - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentNameFromType(Component) || "Unknown"; - if (hasChildWork) { - workInProgress.flags |= Update; - } + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - { - // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } - } + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } + } - break; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentNameFromType(Component) || "Unknown"; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - if (state !== null) { - // whether to retry the primary children, or to skip over it and - // go straight to the fallback. Check the priority of the primary - // child fragment. + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } + } +} - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - if (includesSomeLane(renderLanes, primaryChildLanes)) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - } else { - // The primary child fragment does not have pending work marked - // on it - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. - - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; +} - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - // Note: We can return `null` here because we already checked - // whether there were nested context consumers, via the call to - // `bailoutOnAlreadyFinishedWork` above. - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; - break; - } + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; +} // TODO: Probably should inline this back - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; +function shouldRemainOnFallback( + suspenseContext, + current, + workInProgress, + renderLanes +) { + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallack + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } + } // Not currently showing content. Consult the Suspense context. - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - } // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} - workInProgress.flags |= DidCapture; - } // If nothing suspended before and we're rendering the same children, - // then the tail doesn't matter. Anything new that suspends will work - // in the "together" mode, so we can continue from the state we had. - - var renderState = workInProgress.memoizedState; - - if (renderState !== null) { - // Reset to the "together" mode in case we've started a different - // update in the past but didn't complete it. - renderState.rendering = null; - renderState.tail = null; - renderState.lastEffect = null; - } +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} - pushSuspenseContext(workInProgress, suspenseStackCursor.current); +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; - } - } + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } + } - case OffscreenComponent: - case LegacyHiddenComponent: { - // Need to check if the tree still needs to be deferred. This is - // almost identical to the logic used in the normal update path, - // so we'll just enter that. The only difference is we'll bail out - // at the next level instead of this one, because the child props - // have not changed. Which is fine. - // TODO: Probably should refactor `beginWork` to split the bailout - // path from the normal path. I'm tempted to do a labeled break here - // but I won't :) - workInProgress.lanes = NoLanes; - return updateOffscreenComponent(current, workInProgress, renderLanes); - } - } + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } else { - if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } else { - // An update was scheduled on this fiber, but there are no new props - // nor legacy context. Set this to false. If an update queue or context - // consumer produces a changed value, it will set this to true. Otherwise, - // the component will assume the children have not changed and bail out. - didReceiveUpdate = false; - } - } + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; } else { - didReceiveUpdate = false; - } // Before entering the begin phase, clear pending update priority. - // TODO: This assumes that we're about to evaluate the component and process - // the update queue. However, there's an exception: SimpleMemoComponent - // sometimes bails out later in the begin phase. This indicates that we should - // move this assignment out of the common path and into each branch. + // Attempting the main content + if (current === null || current.memoizedState !== null) { + // This is a new mount or this boundary is already showing a fallback state. + // Mark this subtree context as having at least one invisible parent that could + // handle the fallback state. + // Avoided boundaries are not considered since they cannot handle preferred fallback states. + if (nextProps.unstable_avoidThisFallback !== true) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } + } - workInProgress.lanes = NoLanes; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconcilation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + if (current === null) { + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - elementType, - updateLanes, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - } - - case FunctionComponent: { - var _Component = workInProgress.type; - var unresolvedProps = workInProgress.pendingProps; - var resolvedProps = - workInProgress.elementType === _Component - ? unresolvedProps - : resolveDefaultProps(_Component, unresolvedProps); - return updateFunctionComponent( - current, - workInProgress, - _Component, - resolvedProps, + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState( renderLanes ); - } - - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; - - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); - - return updateClassComponent( - current, + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else if (typeof nextProps.unstable_expectedLoadTime === "number") { + // This is a CPU-bound tree. Skip this tree and show a placeholder to + // unblock the surrounding content. Then immediately retry after the + // initial commit. + var _fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - _Component2, - _resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - } - - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); - - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); - - case HostText: - return updateHostText(); - - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); - - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; - - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); - - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( renderLanes ); - } - - case Fragment: - return updateFragment(current, workInProgress, renderLanes); - - case Mode: - return updateMode(current, workInProgress, renderLanes); - - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to + // get it started back up to attempt the next item. While in terms of + // priority this work has the same priority as this current render, it's + // not part of the same transition once the transition has committed. If + // it's sync, we still want to yield so that it can be painted. + // Conceptually, this is really the same as pinging. We can use any + // RetryLane even if it's the one currently rendering since we're leaving + // it behind on this node. - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + workInProgress.lanes = SomeRetryLane; + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); + } + } else { + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes + ); - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + var _primaryChildFragment3 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment3.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment; + } else { + var _nextPrimaryChildren3 = nextProps.children; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes + ); - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentNameFromType(_type2) - ); - } - } + workInProgress.memoizedState = null; + return _primaryChildFragment4; } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); - } - - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes + ); - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + var _primaryChildFragment5 = workInProgress.child; + var _prevOffscreenState = current.child.memoizedState; + _primaryChildFragment5.memoizedState = + _prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); + _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); // Skip the primary children, and continue working on the + // fallback children. - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); - } + var _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + renderLanes + ); - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); + workInProgress.memoizedState = null; + return _primaryChildFragment6; + } } + } +} - case ScopeComponent: { - break; - } +function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes +) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + if ( + (mode & ConcurrentMode) === NoMode && + progressedPrimaryFragment !== null + ) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; + + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; } - } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; +function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) { + // The props argument to `createFiberFromOffscreen` is `any` typed, so we use + // this wrapper function to constrain it. + return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); } -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; +function updateWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); } -function hadNoMutationsEffects(current, completedWork) { - var didBailout = current !== null && current.child === completedWork.child; +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - if (didBailout) { - return true; + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; } - if ((completedWork.flags & ChildDeletion) !== NoFlags) { - return false; - } // TODO: If we move the `hadNoMutationsEffects` call after `bubbleProperties` - // then we only have to check the `completedWork.subtreeFlags`. + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - var child = completedWork.child; + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - while (child !== null) { - if ( - (child.flags & MutationMask) !== NoFlags || - (child.subtreeFlags & MutationMask) !== NoFlags - ) { - return false; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); } - - child = child.sibling; } - return true; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; +function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; -{ - // Persistent host tree mode - appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration; + primaryChildFragment.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration; + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // We need to complete it now, because we're going to skip over its normal + // complete phase and go straight to rendering the fallback. + var currentOffscreenContainer = currentPrimaryChildFragment.child; + var offscreenContainer = primaryChildFragment.child; + var containerProps = getOffscreenContainerProps( + "hidden", + primaryChildren + ); + offscreenContainer.pendingProps = containerProps; + offscreenContainer.memoizedProps = containerProps; + completeSuspendedOffscreenHostContainer( + currentOffscreenContainer, + offscreenContainer + ); + } // The fallback fiber was added as a deletion during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. + + workInProgress.deletions = null; + } else { + primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); + + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // We need to complete it now, because we're going to skip over its normal + // complete phase and go straight to rendering the fallback. + var _currentOffscreenContainer = currentPrimaryChildFragment.child; + + if (_currentOffscreenContainer !== null) { + var isHidden = true; + + var _offscreenContainer = reconcileOffscreenHostContainer( + currentPrimaryChildFragment, + primaryChildFragment, + isHidden, + primaryChildren, + renderLanes + ); + + _offscreenContainer.memoizedProps = _offscreenContainer.pendingProps; + completeSuspendedOffscreenHostContainer( + _currentOffscreenContainer, + _offscreenContainer + ); + } + } // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) + + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } + + var fallbackChildFragment; + + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + ); + } else { + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. + + fallbackChildFragment.flags |= Placement; + } - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); - } +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === OffscreenComponent && node.memoizedState !== null) { - // The children in this boundary are hidden. Toggle their visibility - // before appending. - var child = node.child; + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - if (child !== null) { - child.return = node; - } + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - appendAllChildren(parent, node, true, true); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } // $FlowFixMe This is correct but Flow is confused by the labeled break. +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderLanes +) { + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; - node = node; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (node === workInProgress) { - return; + if (state !== null) { + scheduleWorkOnFiber(node, renderLanes); } + } else if (node.tag === SuspenseListComponent) { + // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleWorkOnFiber(node, renderLanes); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + if (node === workInProgress) { + return; + } - node = node.return; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - node.sibling.return = node.return; - node = node.sibling; + node = node.return; } - }; // An unfortunate fork of appendAllChildren because we have two different parent types. - var appendAllChildrenToContainer = function( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; + node.sibling.return = node.return; + node = node.sibling; + } +} - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(); - } + row = row.sibling; + } - appendChildToContainerChildSet(containerChildSet, _instance2); - } else if (node.tag === HostPortal); - else if (node.tag === OffscreenComponent && node.memoizedState !== null) { - // The children in this boundary are hidden. Toggle their visibility - // before appending. - var child = node.child; + return lastContentRow; +} - if (child !== null) { - child.return = node; - } +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - appendAllChildrenToContainer(containerChildSet, node, true, true); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } // $FlowFixMe This is correct but Flow is confused by the labeled break. + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - node = node; + break; + } - if (node === workInProgress) { - return; - } + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + break; + } - node = node.return; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); } + } + } +} - node.sibling.return = node.return; - node = node.sibling; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + + error( + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode + ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; + + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } } - }; + } +} - updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); +function validateSuspenseListNestedChild(childSlot, index) { + { + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; - if (childrenUnchanged); - else { - var container = portalOrRoot.containerInfo; - var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set. + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); + return false; } - }; + } - updateHostComponent$1 = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - var currentInstance = current.stateNode; - var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates. - // This guarantees that we can reuse all of them. + return true; +} - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } } + } +} - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; - workInProgress.stateNode = newInstance; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } +} // This can end up rendering this component multiple passes. +// The first pass splits the children fibers into two sets. A head and tail. +// We first render the head. If anything is in fallback state, we do another +// pass through beginWork to rerender all children (including the tail) with +// the force suspend context. If the first render didn't have anything in +// in fallback state. Then we render each row in the tail one-by-one. +// That happens in the completeWork phase without going back to beginWork. - if (childrenUnchanged) { - // If there are no other effects in this tree, we need to flag this node as having one. - // Even though we're not going to use it for anything. - // Otherwise parents won't know that there are new children to propagate upwards. - markUpdate(workInProgress); - } else { - // If children might have changed, we have to add them all to the set. - appendAllChildren(newInstance, workInProgress, false, false); - } - }; +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); - updateHostText$1 = function(current, workInProgress, oldText, newText) { - if (oldText !== newText) { - // If the text content differs, we'll create a new text instance for it. - var rootContainerInstance = getRootHostContainer(); - var currentHostContext = getHostContext(); - workInProgress.stateNode = createTextInstance( - newText, - rootContainerInstance, - currentHostContext, - workInProgress - ); // We'll have to mark it as having an effect, even though we won't use the effect for anything. - // This lets the parents know that at least one of their children has changed. + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, + renderLanes + ); } - }; -} -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var tailNode = renderState.tail; - var lastTailNode = null; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + pushSuspenseContext(workInProgress, suspenseContext); - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; + } else { + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; + } else { + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; + } + + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode + ); + break; } - break; - } + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; - case "collapsed": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var _tailNode = renderState.tail; - var _lastTailNode = null; + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode + ); + break; + } - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; - } else { - renderState.tail = null; - } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined + ); + break; } - break; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } } } + + return workInProgress.child; } -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - if (!didBailout) { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; - var child = completedWork.child; + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. + return workInProgress.child; +} - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; +function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - subtreeFlags |= _child.subtreeFlags; - subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; - _child.return = completedWork; - _child = _child.sibling; + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); } } - completedWork.subtreeFlags |= subtreeFlags; - } else { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var _treeBaseDuration = completedWork.selfBaseDuration; - var _child2 = completedWork.child; + var providerPropTypes = workInProgress.type.propTypes; - while (_child2 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child2.lanes, _child2.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } + } - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; + pushProvider(workInProgress, context, newValue); + + { + if (oldProps !== null) { + var oldValue = oldProps.value; + + if (objectIs(oldValue, newValue)) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, renderLanes); } + } + } - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - while (_child3 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child3.lanes, _child3.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. +var hasWarnedAboutUsingContextAsConsumer = false; - subtreeFlags |= _child3.subtreeFlags & StaticMask; - subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. +function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + // DEV mode, we create a separate object for Context.Consumer that acts + // like a proxy to Context. This proxy object adds unnecessary code in PROD + // so we use the old behaviour (Context.Consumer references Context) to + // reduce size and overhead. The separate object references context via + // a property called "_context", which also gives us the ability to check + // in DEV mode if this property exists or not and warn if it does not. - _child3.return = completedWork; - _child3 = _child3.sibling; + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; + + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); + } } + } else { + context = context._context; } - - completedWork.subtreeFlags |= subtreeFlags; } - completedWork.childLanes = newChildLanes; - return didBailout; -} - -function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; + var render = newProps.children; - switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - bubbleProperties(workInProgress); - return null; + { + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } + } - case ClassComponent: { - var Component = workInProgress.type; + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); - if (isContextProvider(Component)) { - popContext(workInProgress); - } + var newChildren; - bubbleProperties(workInProgress); - return null; - } + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } - case HostRoot: { - var fiberRoot = workInProgress.stateNode; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (current === null || current.child === null) { - // If we hydrated, pop so that we can delete any remaining children - // that weren't hydrated. - var wasHydrated = popHydrationState(); + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } else if (!fiberRoot.hydrate) { - // Schedule an effect to clear this container at the start of the next commit. - // This handles the case of React rendering into a container with previous children. - // It's also safe to do for updates too, because current.child would only be null - // if the previous render was null (so the the container would already be empty). - workInProgress.flags |= Snapshot; - } - } + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + // The children don't have any work either. We can skip them. + // TODO: Once we add back resuming, we should check if the children are + // a work-in-progress set. If so, we need to transfer their effects. + { return null; } + } // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + cloneChildFibers(current, workInProgress); + return workInProgress.child; +} - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - bubbleProperties(workInProgress); - return null; - } + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context - // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on whether we want to add them top->down or - // bottom->up. Top->down is faster in IE11. + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - var _wasHydrated = popHydrationState(); + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (_wasHydrated) { - // TODO: Move this and createInstance step into the beginPhase - // to consolidate. - if (prepareToHydrateHostInstance()) { - // If changes to the hydrated node need to be applied at the - // commit-phase we mark this as such. - markUpdate(workInProgress); - } - } else { - var instance = createInstance( - type, - newProps, - rootContainerInstance, - currentHostContext, - workInProgress - ); - appendAllChildren(instance, workInProgress, false, false); - workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. - } + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); } } - bubbleProperties(workInProgress); - return null; - } - - case HostText: { - var newText = newProps; + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - if (current && workInProgress.stateNode != null) { - var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need - // to schedule a side-effect to do the updates. + var deletions = returnFiber.deletions; - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - } + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); + } - var _rootContainerInstance = getRootHostContainer(); + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - var _currentHostContext = getHostContext(); + return newWorkInProgress; + } +} - var _wasHydrated2 = popHydrationState(); +function checkScheduledUpdateOrContext(current, renderLanes) { + // Before performing an early bailout, we must check if there are pending + // updates or context. + var updateLanes = current.lanes; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } + if (includesSomeLane(updateLanes, renderLanes)) { + return true; + } // No pending update, but because context is propagated lazily, we need - bubbleProperties(workInProgress); - return null; - } + return false; +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; +function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes +) { + // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + case HostComponent: + pushHostContext(workInProgress); + break; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. + case ClassComponent: { + var Component = workInProgress.type; - return workInProgress; + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + break; + } - if (current === null); - else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; - } // If the suspended state of the boundary changes, we need to schedule - // an effect to toggle the subtree's visibility. When we switch from - // fallback -> primary, the inner Offscreen fiber schedules this effect - // as part of its normal complete phase. But when we switch from - // primary -> fallback, the inner Offscreen fiber does not have a complete - // phase. So we need to schedule its effect here. - // - // We also use this flag to connect/disconnect the effects, but the same - // logic applies: when re-connecting, the Offscreen fiber's complete - // phase will handle scheduling the effect. It's only when the fallback - // is active that we have to do anything special. + case HostPortal: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; - if (nextDidTimeout && !prevDidTimeout) { - var offscreenFiber = workInProgress.child; - offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything - // in the concurrent tree already suspended during this render. - // This is a known bug. + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - if ((workInProgress.mode & ConcurrentMode) !== NoMode) { - // TODO: Move this back to throwException because this is too late - // if this is a large tree which is common for initial loads. We - // don't know if we should restart a render or not until we get - // this marker, and this is too late. - // If this render already had a ping or lower pri updates, - // and this is the first time we know we're going to suspend we - // should be able to immediately restart from within throwException. - var hasInvisibleChildContext = - current === null && - workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + if (hasChildWork) { + workInProgress.flags |= Update; + } - if ( - hasInvisibleChildContext || - hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ) - ) { - // If this was in an invisible tree or a new render, then showing - // this boundary is ok. - renderDidSuspend(); - } else { - // Otherwise, we're going to have to hide content so we should - // suspend for longer if possible. - renderDidSuspendDelayIfPossible(); - } + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } } - var wakeables = workInProgress.updateQueue; + break; - if (wakeables !== null) { - // Schedule an effect to attach a retry listener to the promise. - // TODO: Move to passive phase - workInProgress.flags |= Update; - } + case SuspenseComponent: { + var state = workInProgress.memoizedState; - bubbleProperties(workInProgress); + if (state !== null) { + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. - { - if ((workInProgress.mode & ProfileMode) !== NoMode) { - if (nextDidTimeout) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var _primaryChildFragment2 = workInProgress.child; + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doesn't support type casting in combination with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent(current, workInProgress, renderLanes); + } else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + // Note: We can return `null` here because we already checked + // whether there were nested context consumers, via the call to + // `bailoutOnAlreadyFinishedWork` above. + return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } - return null; + break; } - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - bubbleProperties(workInProgress); - return null; + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; + var renderState = workInProgress.memoizedState; - if (isContextProvider(_Component)) { - popContext(workInProgress); + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; } - bubbleProperties(workInProgress); - return null; + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + } } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + case OffscreenComponent: + case LegacyHiddenComponent: { + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + } - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); +} + +function beginWork(current, workInProgress, renderLanes) { + { + if (workInProgress._debugNeedsRemount && current !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.lanes + ) + ); + } + } + + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; + + if ( + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type + ) { + // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + } else { + // Neither props nor legacy context changes. Check if there's a pending + // update or context change. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if ( + !hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there + // may not be work scheduled on `current`, so we check for this flag. + (workInProgress.flags & DidCapture) === NoFlags + ) { + // No pending updates or context. Bail out now. + didReceiveUpdate = false; + return attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } else { + // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; + } + } + } else { + didReceiveUpdate = false; + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. - if (renderedTail === null) { - // We just rendered the head. - if (!didSuspendAlready) { - // This is the first pass. We need to figure out if anything is still - // suspended in the rendered set. - // If new content unsuspended, but there's still some content that - // didn't. Then we need to do a second pass that forces everything - // to keep showing their fallbacks. - // We might be suspended if something in this render pass suspended, or - // something in the previous committed pass suspended. Otherwise, - // there's no chance so we can skip the expensive call to - // findFirstSuspended. - var cannotBeSuspended = - renderHasNotSuspendedYet() && - (current === null || (current.flags & DidCapture) === NoFlags); + workInProgress.lanes = NoLanes; - if (!cannotBeSuspended) { - var row = workInProgress.child; + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - while (row !== null) { - var suspended = findFirstSuspended(row); + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + renderLanes + ); + } - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.flags |= DidCapture; - cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as - // part of the second pass. In that case nothing will subscribe to - // its thennables. Instead, we'll transfer its thennables to the - // SuspenseList so that it can retry if they resolve. - // There might be multiple of these in the list but since we're - // going to wait for all of them anyway, it doesn't really matter - // which ones gets to ping. In theory we could get clever and keep - // track of how many dependencies remain but it gets tricky because - // in the meantime, we can add/remove/change items and dependencies. - // We might bail out of the loop before finding any but that - // doesn't matter since that means that the other boundaries that - // we did find already has their listeners attached. + case FunctionComponent: { + var Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + return updateFunctionComponent( + current, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + } + + case ClassComponent: { + var _Component = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; + + var _resolvedProps = + workInProgress.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + return updateClassComponent( + current, + workInProgress, + _Component, + _resolvedProps, + renderLanes + ); + } - var newThennables = suspended.updateQueue; + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect flags before doing the second pass since that's now invalid. - // Reset the child fibers to their original state. + case HostComponent: + return updateHostComponent$1(current, workInProgress, renderLanes); - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + case HostText: + return updateHostText$1(); - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - return workInProgress.child; - } + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - row = row.sibling; - } - } + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (renderState.tail !== null && now() > getRenderTargetTime()) { - // We have already passed our CPU deadline but we still have rows - // left in the tail. We'll just give up further attempts to render - // the main content and only render fallbacks. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - workInProgress.lanes = SomeRetryLane; - } - } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } - if (_suspended !== null) { - workInProgress.flags |= DidCapture; - didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't - // get lost if this row ends up dropped during a second pass. + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - var _newThennables = _suspended.updateQueue; + case Mode: + return updateMode(current, workInProgress, renderLanes); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - cutOffTailIfNeeded(renderState, true); // This might have been modified. + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We're done. - bubbleProperties(workInProgress); - return null; - } - } else if ( - // The time it took to render last row is greater than the remaining - // time we have to render. So rendering one more row would likely - // exceed it. - now() * 2 - renderState.renderingStartTime > - getRenderTargetTime() && - renderLanes !== OffscreenLane - ) { - // We have now passed our CPU deadline and we'll just give up further - // attempts to render the main content and only render fallbacks. - // The assumption is that this is usually faster. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - workInProgress.lanes = SomeRetryLane; - } - } + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - if (renderState.isBackwards) { - // The effect list of the backwards tail will have been added - // to the end. This breaks the guarantee that life-cycles fire in - // sibling order but that isn't a strong guarantee promised by React. - // Especially since these might also just pop in during future commits. - // Append to the beginning of the list. - renderedTail.sibling = workInProgress.child; - workInProgress.child = renderedTail; - } else { - var previousSibling = renderState.last; + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - renderState.last = renderedTail; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentNameFromType(_type2) + ); + } } } - if (renderState.tail !== null) { - // We still have tail rows to render. - // Pop a row. - var next = renderState.tail; - renderState.rendering = next; - renderState.tail = next.sibling; - renderState.renderingStartTime = now(); - next.sibling = null; // Restore the context. - // TODO: We can probably just avoid popping it instead and only - // setting it the first time we go from not suspended to suspended. + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + renderLanes + ); + } - var suspenseContext = suspenseStackCursor.current; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + renderLanes + ); + } - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + case IncompleteClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. + var _resolvedProps4 = + workInProgress.elementType === _Component2 + ? _unresolvedProps4 + : resolveDefaultProps(_Component2, _unresolvedProps4); - return next; - } + return mountIncompleteClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps4, + renderLanes + ); + } - bubbleProperties(workInProgress); - return null; + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); } case ScopeComponent: { break; } - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); - var _nextState = workInProgress.memoizedState; - var nextIsHidden = _nextState !== null; - - if (current !== null) { - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" && // LegacyHidden doesn't do any hiding — it only pre-renders. - workInProgress.tag !== LegacyHiddenComponent - ) { - workInProgress.flags |= Visibility; - } - } - - if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { - bubbleProperties(workInProgress); - } else { - // Don't bubble properties for hidden children unless we're rendering - // at offscreen priority. - if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { - bubbleProperties(workInProgress); - } - } + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } - return null; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); } } @@ -21742,6 +21996,16 @@ function createFiberFromTypeAndProps( return fiber; } +function createOffscreenHostContainerFiber(props, fiberMode, lanes, key) { + { + var type = getOffscreenContainerType(); + var fiber = createFiber(HostComponent, props, key, fiberMode); + fiber.elementType = type; + fiber.type = type; + fiber.lanes = lanes; + return fiber; + } +} function createFiberFromElement(element, mode, lanes) { var owner = null; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 829170b1fe9a5c..9fb895dc95798a 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,13 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<8066df1aa410b680ab0fb087ce46a9a4>> + * @generated SignedSource<<15ee7ea73c5753e6994dd769bbe917ca>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), + dynamicFlags = require("ReactNativeInternalFeatureFlags"), Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); @@ -930,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_220 = { +var injectedNamesToPlugins$jscomp$inline_221 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -965,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_220 = { } } }, - isOrderingDirty$jscomp$inline_221 = !1, - pluginName$jscomp$inline_222; -for (pluginName$jscomp$inline_222 in injectedNamesToPlugins$jscomp$inline_220) + isOrderingDirty$jscomp$inline_222 = !1, + pluginName$jscomp$inline_223; +for (pluginName$jscomp$inline_223 in injectedNamesToPlugins$jscomp$inline_221) if ( - injectedNamesToPlugins$jscomp$inline_220.hasOwnProperty( - pluginName$jscomp$inline_222 + injectedNamesToPlugins$jscomp$inline_221.hasOwnProperty( + pluginName$jscomp$inline_223 ) ) { - var pluginModule$jscomp$inline_223 = - injectedNamesToPlugins$jscomp$inline_220[pluginName$jscomp$inline_222]; + var pluginModule$jscomp$inline_224 = + injectedNamesToPlugins$jscomp$inline_221[pluginName$jscomp$inline_223]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_222) || - namesToPlugins[pluginName$jscomp$inline_222] !== - pluginModule$jscomp$inline_223 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_223) || + namesToPlugins[pluginName$jscomp$inline_223] !== + pluginModule$jscomp$inline_224 ) { - if (namesToPlugins[pluginName$jscomp$inline_222]) + if (namesToPlugins[pluginName$jscomp$inline_223]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_222 + + pluginName$jscomp$inline_223 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_222 - ] = pluginModule$jscomp$inline_223; - isOrderingDirty$jscomp$inline_221 = !0; + pluginName$jscomp$inline_223 + ] = pluginModule$jscomp$inline_224; + isOrderingDirty$jscomp$inline_222 = !0; } } -isOrderingDirty$jscomp$inline_221 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_222 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1181,6 +1182,8 @@ function getComponentNameFromFiber(fiber) { } return null; } +var enablePersistentOffscreenHostContainer = + dynamicFlags.enablePersistentOffscreenHostContainer; function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1870,30 +1873,73 @@ var ReactFabricHostComponent = (function() { ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + null != stateNode && + fabricMeasure( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); }; _proto.measureInWindow = function(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + null != stateNode && + fabricMeasureInWindow( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); }; _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - "number" !== typeof relativeToNativeNode && - relativeToNativeNode instanceof ReactFabricHostComponent && - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); + if ( + "number" !== typeof relativeToNativeNode && + relativeToNativeNode instanceof ReactFabricHostComponent + ) { + var toStateNode = this._internalInstanceHandle.stateNode; + relativeToNativeNode = + relativeToNativeNode._internalInstanceHandle.stateNode; + null != toStateNode && + null != relativeToNativeNode && + fabricMeasureLayout( + toStateNode.node, + relativeToNativeNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } }; _proto.setNativeProps = function() {}; return ReactFabricHostComponent; })(); +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + hostContext = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + props, + type.validAttributes + ); + rootContainerInstance = createNode( + hostContext, + type.uiViewClassName, + rootContainerInstance, + updatePayload, + internalInstanceHandle + ); + props = new ReactFabricHostComponent( + hostContext, + type, + props, + internalInstanceHandle + ); + return { node: rootContainerInstance, canonical: props }; +} function createTextInstance( text, rootContainerInstance, @@ -1916,6 +1962,11 @@ function createTextInstance( } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout; +function getOffscreenContainerProps(mode, children) { + return "hidden" === mode + ? { children: children, style: { display: "none" } } + : { children: children, style: { flex: 1 } }; +} function cloneHiddenInstance(instance) { var node = instance.node; var JSCompiler_inline_result = diffProperties( @@ -4064,178 +4115,736 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, - didReceiveUpdate = !1; -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - workInProgress.child = - null === current - ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) - : reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); -} -function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - Component = Component.render; - var ref = workInProgress.ref; - prepareToReadContext(workInProgress, renderLanes); - nextProps = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - ref, - renderLanes - ); - if (null !== current && !didReceiveUpdate) - return ( - (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), - (current.lanes &= ~renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } -function updateMemoComponent( - current, +var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; +appendAllChildren = function( + parent, workInProgress, - Component, - nextProps, - updateLanes, - renderLanes + needsVisibilityToggle, + isHidden ) { - if (null === current) { - var type = Component.type; - if ( - "function" === typeof type && - !shouldConstruct(type) && - void 0 === type.defaultProps && - null === Component.compare && - void 0 === Component.defaultProps - ) - return ( - (workInProgress.tag = 15), - (workInProgress.type = type), - updateSimpleMemoComponent( - current, - workInProgress, - type, - nextProps, - updateLanes, - renderLanes - ) - ); - current = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNode(parent.node, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNode(parent.node, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + enablePersistentOffscreenHostContainer + ? appendAllChildren(parent, node, !1, !1) + : appendAllChildren(parent, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - type = current.child; - if ( - 0 === (updateLanes & renderLanes) && - ((updateLanes = type.memoizedProps), - (Component = Component.compare), - (Component = null !== Component ? Component : shallowEqual), - Component(updateLanes, nextProps) && current.ref === workInProgress.ref) - ) - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - workInProgress.flags |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); -} -function updateSimpleMemoComponent( - current, +}; +function appendAllChildrenToContainer( + containerChildSet, workInProgress, - Component, - nextProps, - updateLanes, - renderLanes + needsVisibilityToggle, + isHidden ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + enablePersistentOffscreenHostContainer + ? appendAllChildrenToContainer(containerChildSet, node, !1, !1) + : appendAllChildrenToContainer(containerChildSet, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); } -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - nextChildren = nextProps.children, - prevState = null !== current ? current.memoizedState : null; +updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); + appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); + portalOrRoot.pendingChildren = newChildSet; + workInProgress.flags |= 4; + completeRoot(current, newChildSet); + } +}; +updateHostComponent = function(current, workInProgress, type, newProps) { + type = current.stateNode; + var oldProps = current.memoizedProps; if ( - "hidden" === nextProps.mode || - "unstable-defer-without-hiding" === nextProps.mode + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps ) - if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= renderLanes); - else { - if (0 === (renderLanes & 1073741824)) - return ( - (current = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { - baseLanes: current, - cachePool: null - }), - (workInProgress.updateQueue = null), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= current), - null - ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } - else - null !== prevState - ? ((nextProps = prevState.baseLanes | renderLanes), + workInProgress.stateNode = type; + else { + var recyclableInstance = workInProgress.stateNode; + requiredContext(contextStackCursor$1.current); + var updatePayload = null; + oldProps !== newProps && + ((oldProps = diffProperties( + null, + oldProps, + newProps, + recyclableInstance.canonical.viewConfig.validAttributes + )), + (recyclableInstance.canonical.currentProps = newProps), + (updatePayload = oldProps)); + current && null === updatePayload + ? (workInProgress.stateNode = type) + : ((newProps = updatePayload), + (oldProps = type.node), + (type = { + node: current + ? null !== newProps + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) + : null !== newProps + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), + canonical: type.canonical + }), + (workInProgress.stateNode = type), + current + ? (workInProgress.flags |= 4) + : appendAllChildren(type, workInProgress, !1, !1)); + } +}; +updateHostText = function(current, workInProgress, oldText, newText) { + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.flags |= 4)) + : (workInProgress.stateNode = current.stateNode); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$38 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$38 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$38 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$38.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$39 = completedWork.child; null !== child$39; ) + (newChildLanes |= child$39.lanes | child$39.childLanes), + (subtreeFlags |= child$39.subtreeFlags & 1835008), + (subtreeFlags |= child$39.flags & 1835008), + (child$39.return = completedWork), + (child$39 = child$39.sibling); + else + for (child$39 = completedWork.child; null !== child$39; ) + (newChildLanes |= child$39.lanes | child$39.childLanes), + (subtreeFlags |= child$39.subtreeFlags), + (subtreeFlags |= child$39.flags), + (child$39.return = completedWork), + (child$39 = child$39.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeSuspendedOffscreenHostContainer(current, workInProgress) { + var rootContainerInstance = requiredContext(rootInstanceStackCursor.current), + type = workInProgress.type, + newProps = workInProgress.memoizedProps; + null !== current + ? updateHostComponent( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) + : ((current = requiredContext(contextStackCursor$1.current)), + (rootContainerInstance = createInstance( + type, + newProps, + rootContainerInstance, + current, + workInProgress + )), + appendAllChildren(rootContainerInstance, workInProgress, !1, !1), + (workInProgress.stateNode = rootContainerInstance), + null !== workInProgress.ref && (workInProgress.flags |= 256)); + bubbleProperties(workInProgress); +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (newProps = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + newProps.pendingContext && + ((newProps.context = newProps.pendingContext), + (newProps.pendingContext = null)), + (null !== current && null !== current.child) || + newProps.hydrate || + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + current = requiredContext(contextStackCursor$1.current); + current = createInstance( + type, + newProps, + renderLanes, + current, + workInProgress + ); + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.flags |= 256); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + renderLanes = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + renderLanes, + workInProgress + ); + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.flags & 128)) + return (workInProgress.lanes = renderLanes), workInProgress; + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if ( + null !== newProps && + !renderLanes && + ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) + ) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3); + else { + if ( + 0 === workInProgressRootExitStatus || + 3 === workInProgressRootExitStatus + ) + workInProgressRootExitStatus = 4; + null === workInProgressRoot || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || + markRootSuspended$1( + workInProgressRoot, + workInProgressRootRenderLanes + ); + } + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + var renderedTail = type.rendering; + if (null === renderedTail) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + renderedTail = findFirstSuspended(current); + if (null !== renderedTail) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = renderedTail.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (newProps = workInProgress.child; null !== newProps; ) + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 1835010), + (renderedTail = renderLanes.alternate), + null === renderedTail + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = type), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null)) + : ((renderLanes.childLanes = renderedTail.childLanes), + (renderLanes.lanes = renderedTail.lanes), + (renderLanes.child = renderedTail.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = + renderedTail.memoizedProps), + (renderLanes.memoizedState = + renderedTail.memoizedState), + (renderLanes.updateQueue = renderedTail.updateQueue), + (renderLanes.type = renderedTail.type), + (type = renderedTail.dependencies), + (renderLanes.dependencies = + null === type + ? null + : { + lanes: type.lanes, + firstContext: type.firstContext + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(renderedTail)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !renderedTail.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((renderedTail.sibling = workInProgress.child), + (workInProgress.child = renderedTail)) + : ((current = type.last), + null !== current + ? (current.sibling = renderedTail) + : (workInProgress.child = renderedTail), + (type.last = renderedTail)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + "unstable-defer-without-hiding" !== newProps.mode && + 23 !== workInProgress.tag && + (workInProgress.flags |= 4096), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + bubbleProperties(workInProgress) + : bubbleProperties(workInProgress), + null + ); + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + didReceiveUpdate = !1; +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + workInProgress.child = + null === current + ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) + : reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); +} +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + Component = Component.render; + var ref = workInProgress.ref; + prepareToReadContext(workInProgress, renderLanes); + nextProps = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + ref, + renderLanes + ); + if (null !== current && !didReceiveUpdate) + return ( + (workInProgress.updateQueue = current.updateQueue), + (workInProgress.flags &= -1029), + (current.lanes &= ~renderLanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + workInProgress.flags |= 1; + reconcileChildren(current, workInProgress, nextProps, renderLanes); + return workInProgress.child; +} +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if (null === current) { + var type = Component.type; + if ( + "function" === typeof type && + !shouldConstruct(type) && + void 0 === type.defaultProps && + null === Component.compare && + void 0 === Component.defaultProps + ) + return ( + (workInProgress.tag = 15), + (workInProgress.type = type), + updateSimpleMemoComponent( + current, + workInProgress, + type, + nextProps, + renderLanes + ) + ); + current = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); + } + type = current.child; + if (0 === (current.lanes & renderLanes)) { + var prevProps = type.memoizedProps; + Component = Component.compare; + Component = null !== Component ? Component : shallowEqual; + if (Component(prevProps, nextProps) && current.ref === workInProgress.ref) + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + workInProgress.flags |= 1; + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); +} +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if ( + null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref + ) + if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps, + nextChildren = nextProps.children, + prevState = null !== current ? current.memoizedState : null; + if ( + "hidden" === nextProps.mode || + "unstable-defer-without-hiding" === nextProps.mode + ) + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + prevState = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= prevState; + } + else + null !== prevState + ? ((prevState = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) - : (nextProps = renderLanes), + : (prevState = renderLanes), push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + (subtreeRenderLanes |= prevState); + if (enablePersistentOffscreenHostContainer) + return reconcileOffscreenHostContainer( + current, + workInProgress, + "hidden" === nextProps.mode && 23 !== workInProgress.tag, + nextChildren, + renderLanes + ); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { +function reconcileOffscreenHostContainer( + currentOffscreen, + offscreen, + isHidden, + children, + renderLanes +) { + isHidden = getOffscreenContainerProps( + isHidden ? "hidden" : "visible", + children + ); + null === currentOffscreen + ? (renderLanes = createOffscreenHostContainerFiber( + isHidden, + offscreen.mode, + renderLanes, + null + )) + : ((currentOffscreen = currentOffscreen.child), + null === currentOffscreen + ? ((renderLanes = createOffscreenHostContainerFiber( + isHidden, + offscreen.mode, + renderLanes, + null + )), + (renderLanes.flags |= 2)) + : (renderLanes = createWorkInProgress(currentOffscreen, isHidden))); + renderLanes.return = offscreen; + return (offscreen.child = renderLanes); +} +function markRef$1(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4484,7 +5093,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef(current, workInProgress); + markRef$1(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -4583,7 +5192,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes = createFiberFromOffscreen( { mode: "visible", children: current }, workInProgress.mode, - renderLanes, + 0, null ); renderLanes.return = workInProgress; @@ -4711,17 +5320,49 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child, + currentFallbackChildFragment = currentPrimaryChildFragment.sibling, primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), + 0 === (mode & 1) && workInProgress.child !== currentPrimaryChildFragment + ? ((current = workInProgress.child), + (current.childLanes = 0), + (current.pendingProps = primaryChildProps), + enablePersistentOffscreenHostContainer && + ((currentPrimaryChildFragment = currentPrimaryChildFragment.child), + (primaryChildProps = current.child), + (primaryChildren = getOffscreenContainerProps( + "hidden", + primaryChildren + )), + (primaryChildProps.pendingProps = primaryChildren), + (primaryChildProps.memoizedProps = primaryChildren), + completeSuspendedOffscreenHostContainer( + currentPrimaryChildFragment, + primaryChildProps + )), (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + : ((current = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )), + enablePersistentOffscreenHostContainer && + ((primaryChildProps = currentPrimaryChildFragment.child), + null !== primaryChildProps && + ((primaryChildren = reconcileOffscreenHostContainer( + currentPrimaryChildFragment, + current, + !0, + primaryChildren, + renderLanes + )), + (primaryChildren.memoizedProps = primaryChildren.pendingProps), + completeSuspendedOffscreenHostContainer( + primaryChildProps, + primaryChildren + ))), + (current.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -4735,9 +5376,9 @@ function updateSuspenseFallbackChildren( )), (fallbackChildren.flags |= 2)); fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; + current.return = workInProgress; + current.sibling = fallbackChildren; + workInProgress.child = current; return fallbackChildren; } function scheduleWorkOnFiber(fiber, renderLanes) { @@ -4877,519 +5518,72 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { } return workInProgress.child; } -function hadNoMutationsEffects(current, completedWork) { - if (null !== current && current.child === completedWork.child) return !0; - if (0 !== (completedWork.flags & 16)) return !1; - for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) - return !1; - current = current.sibling; - } - return !0; -} -var appendAllChildren, - updateHostContainer, - updateHostComponent$1, - updateHostText$1; -appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNode(parent.node, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNode(parent.node, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildren(parent, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -function appendAllChildrenToContainer( - containerChildSet, +function attemptEarlyBailoutIfNoScheduledUpdate( + current, workInProgress, - needsVisibilityToggle, - isHidden + renderLanes ) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildrenToContainer(containerChildSet, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -} -updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); - appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); - portalOrRoot.pendingChildren = newChildSet; - workInProgress.flags |= 4; - completeRoot(current, newChildSet); - } -}; -updateHostComponent$1 = function(current, workInProgress, type, newProps) { - type = current.stateNode; - var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) - workInProgress.stateNode = type; - else { - var recyclableInstance = workInProgress.stateNode; - requiredContext(contextStackCursor$1.current); - var updatePayload = null; - oldProps !== newProps && - ((oldProps = diffProperties( - null, - oldProps, - newProps, - recyclableInstance.canonical.viewConfig.validAttributes - )), - (recyclableInstance.canonical.currentProps = newProps), - (updatePayload = oldProps)); - current && null === updatePayload - ? (workInProgress.stateNode = type) - : ((newProps = updatePayload), - (oldProps = type.node), - (type = { - node: current - ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) - : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), - canonical: type.canonical - }), - (workInProgress.stateNode = type), - current - ? (workInProgress.flags |= 4) - : appendAllChildren(type, workInProgress, !1, !1)); - } -}; -updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.flags |= 4)) - : (workInProgress.stateNode = current.stateNode); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$69 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$69 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$69 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$69.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$70 = completedWork.child; null !== child$70; ) - (newChildLanes |= child$70.lanes | child$70.childLanes), - (subtreeFlags |= child$70.subtreeFlags & 1835008), - (subtreeFlags |= child$70.flags & 1835008), - (child$70.return = completedWork), - (child$70 = child$70.sibling); - else - for (child$70 = completedWork.child; null !== child$70; ) - (newChildLanes |= child$70.lanes | child$70.childLanes), - (subtreeFlags |= child$70.subtreeFlags), - (subtreeFlags |= child$70.flags), - (child$70.return = completedWork), - (child$70 = child$70.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - renderLanes = createNode( - current, - type.uiViewClassName, - renderLanes, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - type, - newProps, - workInProgress - ); - current = { node: renderLanes, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 256); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; + case 10: + var context = workInProgress.type._context, + nextValue = workInProgress.memoizedProps.value; + push(valueCursor, context._currentValue2); + context._currentValue2 = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent(current, workInProgress, renderLanes); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + current = bailoutOnAlreadyFinishedWork( current, workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - renderLanes = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, - current, - renderLanes, - workInProgress + renderLanes ); + return null !== current ? current.sibling : null; } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return (workInProgress.lanes = renderLanes), workInProgress; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if ( - null !== newProps && - !renderLanes && - ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) - ) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3); - else { - if ( - 0 === workInProgressRootExitStatus || - 3 === workInProgressRootExitStatus - ) - workInProgressRootExitStatus = 4; - null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || - markRootSuspended$1( - workInProgressRoot, - workInProgressRootRenderLanes - ); - } - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 1835010), - (updatePayload = renderLanes.alternate), - null === updatePayload - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = type), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null)) - : ((renderLanes.childLanes = updatePayload.childLanes), - (renderLanes.lanes = updatePayload.lanes), - (renderLanes.child = updatePayload.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = - updatePayload.memoizedProps), - (renderLanes.memoizedState = - updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type - ? null - : { - lanes: type.lanes, - firstContext: type.firstContext - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + context = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (context) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (context) break; + else return null; case 22: case 23: return ( - popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== renderLanes && - "unstable-defer-without-hiding" !== newProps.mode && - 23 !== workInProgress.tag && - (workInProgress.flags |= 4096), - renderLanes && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - bubbleProperties(workInProgress) - : bubbleProperties(workInProgress), - null + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5544,8 +5738,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$82 = effect.create; - effect.destroy = create$82(); + var create$83 = effect.create; + effect.destroy = create$83(); } effect = effect.next; } while (effect !== finishedWork); @@ -5728,8 +5922,8 @@ function commitMutationEffects(root, firstChild) { switch (root.tag) { case 13: if (null !== root.memoizedState) { - var current$86 = root.alternate; - if (null === current$86 || null === current$86.memoizedState) + var current$87 = root.alternate; + if (null === current$87 || null === current$87.memoizedState) globalMostRecentFallbackTime = now(); } } @@ -5806,8 +6000,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$83 = firstChild.updateQueue; - if (null !== updateQueue$83) { + var updateQueue$84 = firstChild.updateQueue; + if (null !== updateQueue$84) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -5817,7 +6011,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$83, current); + commitUpdateQueue(firstChild, updateQueue$84, current); } break; case 5: @@ -6389,6 +6583,20 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress$30.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; + if ( + enablePersistentOffscreenHostContainer && + null === workInProgress$30.alternate + ) { + var offscreenContainer = workInProgress$30.child.child; + if (null !== offscreenContainer) { + var containerProps = getOffscreenContainerProps( + "hidden", + offscreenContainer.memoizedProps.children + ); + offscreenContainer.pendingProps = containerProps; + offscreenContainer.memoizedProps = containerProps; + } + } if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6882,7 +7090,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; if (null !== current) if ( current.memoizedProps !== workInProgress.pendingProps || @@ -6890,158 +7097,98 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ) didReceiveUpdate = !0; else { - if (0 === (renderLanes & updateLanes)) { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.type._context; - var nextValue = workInProgress.memoizedProps.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = nextValue; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (updateLanes) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; - } - nextValue = workInProgress.memoizedState; - null !== nextValue && - ((nextValue.rendering = null), - (nextValue.tail = null), - (nextValue.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes + if ( + 0 === (current.lanes & renderLanes) && + 0 === (workInProgress.flags & 128) + ) + return ( + (didReceiveUpdate = !1), + attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) ); - } didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { case 2: - updateLanes = workInProgress.type; + var Component = workInProgress.type; null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + var context = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, - updateLanes, + Component, current, - nextValue, + context, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof nextValue && - null !== nextValue && - "function" === typeof nextValue.render && - void 0 === nextValue.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; workInProgress.updateQueue = null; - if (isContextProvider(updateLanes)) { + if (isContextProvider(Component)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== nextValue.state && void 0 !== nextValue.state - ? nextValue.state + null !== context.state && void 0 !== context.state + ? context.state : null; initializeUpdateQueue(workInProgress); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; - mountClassInstance(workInProgress, updateLanes, current, renderLanes); + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; + mountClassInstance(workInProgress, Component, current, renderLanes); workInProgress = finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, hasContext, renderLanes ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, nextValue, renderLanes), + reconcileChildren(null, workInProgress, context, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - nextValue = workInProgress.elementType; + Component = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = nextValue._init; - nextValue = hasContext(nextValue._payload); - workInProgress.type = nextValue; - hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); - current = resolveDefaultProps(nextValue, current); - switch (hasContext) { + context = Component._init; + Component = context(Component._payload); + workInProgress.type = Component; + context = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (context) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7050,7 +7197,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7059,7 +7206,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7068,79 +7215,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), - updateLanes, + Component, + resolveDefaultProps(Component.type, current), renderLanes ); break a; } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + Component + ". Lazy element type must resolve to a class or function." ); } return workInProgress; case 0: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateFunctionComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 1: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateClassComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 3: pushHostRootContext(workInProgress); - updateLanes = workInProgress.updateQueue; - if (null === current || null === updateLanes) + Component = workInProgress.updateQueue; + if (null === current || null === Component) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - nextValue = workInProgress.pendingProps; - updateLanes = workInProgress.memoizedState.element; + context = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, context, null, renderLanes); + context = workInProgress.memoizedState.element; + context === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, context, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: return ( pushHostContext(workInProgress), - (updateLanes = workInProgress.pendingProps.children), - markRef(current, workInProgress), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + (Component = workInProgress.pendingProps.children), + markRef$1(current, workInProgress), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -7153,35 +7299,30 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (updateLanes = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - updateLanes, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - updateLanes, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateForwardRef( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); @@ -7217,16 +7358,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); case 10: a: { - updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + Component = workInProgress.type._context; + context = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - var newValue = nextValue.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = newValue; + var newValue = context.value; + push(valueCursor, Component._currentValue2); + Component._currentValue2 = newValue; if (null !== hasContext) if (objectIs(hasContext.value, newValue)) { if ( - hasContext.children === nextValue.children && + hasContext.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7251,7 +7392,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { null !== dependency; ) { - if (dependency.context === updateLanes) { + if (dependency.context === Component) { if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; @@ -7302,7 +7443,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7310,29 +7451,25 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), - (updateLanes = workInProgress.pendingProps.children), + (context = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context)), + (Component = Component(context)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), - (hasContext = resolveDefaultProps( - nextValue, - workInProgress.pendingProps - )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (Component = workInProgress.type), + (context = resolveDefaultProps(Component, workInProgress.pendingProps)), + (context = resolveDefaultProps(Component.type, context)), updateMemoComponent( current, workInProgress, - nextValue, - hasContext, - updateLanes, + Component, + context, renderLanes ) ); @@ -7342,32 +7479,31 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.type, workInProgress.pendingProps, - updateLanes, renderLanes ); case 17: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)), (workInProgress.tag = 1), - isContextProvider(updateLanes) + isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, Component, context), + mountClassInstance(workInProgress, Component, context, renderLanes), finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, current, renderLanes @@ -7542,6 +7678,13 @@ function createFiberFromTypeAndProps( key.lanes = lanes; return key; } +function createOffscreenHostContainerFiber(props, fiberMode, lanes, key) { + props = createFiber(5, props, key, fiberMode); + props.elementType = "RCTView"; + props.type = "RCTView"; + props.lanes = lanes; + return props; +} function createFiberFromFragment(elements, mode, lanes, key) { elements = createFiber(7, elements, key, mode); elements.lanes = lanes; @@ -7789,10 +7932,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_949 = { + devToolsConfig$jscomp$inline_948 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "18.0.0-419cc9c37-20210726", + version: "18.0.0-19092ac8c-20210803", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7807,11 +7950,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1186 = { - bundleType: devToolsConfig$jscomp$inline_949.bundleType, - version: devToolsConfig$jscomp$inline_949.version, - rendererPackageName: devToolsConfig$jscomp$inline_949.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_949.rendererConfig, +var internals$jscomp$inline_1189 = { + bundleType: devToolsConfig$jscomp$inline_948.bundleType, + version: devToolsConfig$jscomp$inline_948.version, + rendererPackageName: devToolsConfig$jscomp$inline_948.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_948.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7827,26 +7970,26 @@ var internals$jscomp$inline_1186 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_949.findFiberByHostInstance || + devToolsConfig$jscomp$inline_948.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-419cc9c37-20210726" + reconcilerVersion: "18.0.0-19092ac8c-20210803" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1187 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1190 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1187.isDisabled && - hook$jscomp$inline_1187.supportsFiber + !hook$jscomp$inline_1190.isDisabled && + hook$jscomp$inline_1190.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1187.inject( - internals$jscomp$inline_1186 + (rendererID = hook$jscomp$inline_1190.inject( + internals$jscomp$inline_1189 )), - (injectedHook = hook$jscomp$inline_1187); + (injectedHook = hook$jscomp$inline_1190); } catch (err) {} } exports.createPortal = function(children, containerTag) { diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 6163d4f5d15951..760510e0f5af8c 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,13 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<22328f19c763e55197c392c576a84313>> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), React = require("react"), + dynamicFlags = require("ReactNativeInternalFeatureFlags"), Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); @@ -930,7 +931,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_228 = { +var injectedNamesToPlugins$jscomp$inline_229 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -965,34 +966,34 @@ var injectedNamesToPlugins$jscomp$inline_228 = { } } }, - isOrderingDirty$jscomp$inline_229 = !1, - pluginName$jscomp$inline_230; -for (pluginName$jscomp$inline_230 in injectedNamesToPlugins$jscomp$inline_228) + isOrderingDirty$jscomp$inline_230 = !1, + pluginName$jscomp$inline_231; +for (pluginName$jscomp$inline_231 in injectedNamesToPlugins$jscomp$inline_229) if ( - injectedNamesToPlugins$jscomp$inline_228.hasOwnProperty( - pluginName$jscomp$inline_230 + injectedNamesToPlugins$jscomp$inline_229.hasOwnProperty( + pluginName$jscomp$inline_231 ) ) { - var pluginModule$jscomp$inline_231 = - injectedNamesToPlugins$jscomp$inline_228[pluginName$jscomp$inline_230]; + var pluginModule$jscomp$inline_232 = + injectedNamesToPlugins$jscomp$inline_229[pluginName$jscomp$inline_231]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_230) || - namesToPlugins[pluginName$jscomp$inline_230] !== - pluginModule$jscomp$inline_231 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_231) || + namesToPlugins[pluginName$jscomp$inline_231] !== + pluginModule$jscomp$inline_232 ) { - if (namesToPlugins[pluginName$jscomp$inline_230]) + if (namesToPlugins[pluginName$jscomp$inline_231]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_230 + + pluginName$jscomp$inline_231 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_230 - ] = pluginModule$jscomp$inline_231; - isOrderingDirty$jscomp$inline_229 = !0; + pluginName$jscomp$inline_231 + ] = pluginModule$jscomp$inline_232; + isOrderingDirty$jscomp$inline_230 = !0; } } -isOrderingDirty$jscomp$inline_229 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_230 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -1181,6 +1182,8 @@ function getComponentNameFromFiber(fiber) { } return null; } +var enablePersistentOffscreenHostContainer = + dynamicFlags.enablePersistentOffscreenHostContainer; function getNearestMountedFiber(fiber) { var node = fiber, nearestMounted = fiber; @@ -1918,30 +1921,73 @@ var ReactFabricHostComponent = (function() { ReactNativePrivateInterface.TextInputState.focusTextInput(this); }; _proto.measure = function(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + null != stateNode && + fabricMeasure( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); }; _proto.measureInWindow = function(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); + var stateNode = this._internalInstanceHandle.stateNode; + null != stateNode && + fabricMeasureInWindow( + stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); }; _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - "number" !== typeof relativeToNativeNode && - relativeToNativeNode instanceof ReactFabricHostComponent && - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); + if ( + "number" !== typeof relativeToNativeNode && + relativeToNativeNode instanceof ReactFabricHostComponent + ) { + var toStateNode = this._internalInstanceHandle.stateNode; + relativeToNativeNode = + relativeToNativeNode._internalInstanceHandle.stateNode; + null != toStateNode && + null != relativeToNativeNode && + fabricMeasureLayout( + toStateNode.node, + relativeToNativeNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + } }; _proto.setNativeProps = function() {}; return ReactFabricHostComponent; })(); +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + hostContext = nextReactTag; + nextReactTag += 2; + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + props, + type.validAttributes + ); + rootContainerInstance = createNode( + hostContext, + type.uiViewClassName, + rootContainerInstance, + updatePayload, + internalInstanceHandle + ); + props = new ReactFabricHostComponent( + hostContext, + type, + props, + internalInstanceHandle + ); + return { node: rootContainerInstance, canonical: props }; +} function createTextInstance( text, rootContainerInstance, @@ -1964,6 +2010,11 @@ function createTextInstance( } var scheduleTimeout = setTimeout, cancelTimeout = clearTimeout; +function getOffscreenContainerProps(mode, children) { + return "hidden" === mode + ? { children: children, style: { display: "none" } } + : { children: children, style: { flex: 1 } }; +} function cloneHiddenInstance(instance) { var node = instance.node; var JSCompiler_inline_result = diffProperties( @@ -4170,178 +4221,785 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, - didReceiveUpdate = !1; -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - workInProgress.child = - null === current - ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) - : reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); -} -function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - Component = Component.render; - var ref = workInProgress.ref; - prepareToReadContext(workInProgress, renderLanes); - nextProps = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - ref, - renderLanes - ); - if (null !== current && !didReceiveUpdate) - return ( - (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), - (current.lanes &= ~renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; +function hadNoMutationsEffects(current, completedWork) { + if (null !== current && current.child === completedWork.child) return !0; + if (0 !== (completedWork.flags & 16)) return !1; + for (current = completedWork.child; null !== current; ) { + if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) + return !1; + current = current.sibling; + } + return !0; } -function updateMemoComponent( - current, +var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; +appendAllChildren = function( + parent, workInProgress, - Component, - nextProps, - updateLanes, - renderLanes + needsVisibilityToggle, + isHidden ) { - if (null === current) { - var type = Component.type; - if ( - "function" === typeof type && - !shouldConstruct(type) && - void 0 === type.defaultProps && - null === Component.compare && - void 0 === Component.defaultProps - ) - return ( - (workInProgress.tag = 15), - (workInProgress.type = type), - updateSimpleMemoComponent( - current, - workInProgress, - type, - nextProps, - updateLanes, - renderLanes - ) - ); - current = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNode(parent.node, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNode(parent.node, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + enablePersistentOffscreenHostContainer + ? appendAllChildren(parent, node, !1, !1) + : appendAllChildren(parent, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - type = current.child; - if ( - 0 === (updateLanes & renderLanes) && - ((updateLanes = type.memoizedProps), - (Component = Component.compare), - (Component = null !== Component ? Component : shallowEqual), - Component(updateLanes, nextProps) && current.ref === workInProgress.ref) - ) - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - workInProgress.flags |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); -} -function updateSimpleMemoComponent( - current, +}; +function appendAllChildrenToContainer( + containerChildSet, workInProgress, - Component, - nextProps, - updateLanes, - renderLanes + needsVisibilityToggle, + isHidden ) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag) { + var instance = node.stateNode; + needsVisibilityToggle && + isHidden && + (instance = cloneHiddenInstance(instance)); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (6 === node.tag) { + instance = node.stateNode; + if (needsVisibilityToggle && isHidden) + throw Error("Not yet implemented."); + appendChildNodeToSet(containerChildSet, instance.node); + } else if (4 !== node.tag) + if (22 === node.tag && null !== node.memoizedState) + (instance = node.child), + null !== instance && (instance.return = node), + enablePersistentOffscreenHostContainer + ? appendAllChildrenToContainer(containerChildSet, node, !1, !1) + : appendAllChildrenToContainer(containerChildSet, node, !0, !0); + else if (null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); } -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - nextChildren = nextProps.children, - prevState = null !== current ? current.memoizedState : null; +updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); + appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); + portalOrRoot.pendingChildren = newChildSet; + workInProgress.flags |= 4; + completeRoot(current, newChildSet); + } +}; +updateHostComponent = function(current, workInProgress, type, newProps) { + type = current.stateNode; + var oldProps = current.memoizedProps; if ( - "hidden" === nextProps.mode || - "unstable-defer-without-hiding" === nextProps.mode + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps ) - if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= renderLanes); - else { - if (0 === (renderLanes & 1073741824)) - return ( - (current = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { - baseLanes: current, - cachePool: null - }), - (workInProgress.updateQueue = null), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= current), - null - ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } - else - null !== prevState - ? ((nextProps = prevState.baseLanes | renderLanes), + workInProgress.stateNode = type; + else { + var recyclableInstance = workInProgress.stateNode; + requiredContext(contextStackCursor$1.current); + var updatePayload = null; + oldProps !== newProps && + ((oldProps = diffProperties( + null, + oldProps, + newProps, + recyclableInstance.canonical.viewConfig.validAttributes + )), + (recyclableInstance.canonical.currentProps = newProps), + (updatePayload = oldProps)); + current && null === updatePayload + ? (workInProgress.stateNode = type) + : ((newProps = updatePayload), + (oldProps = type.node), + (type = { + node: current + ? null !== newProps + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) + : null !== newProps + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), + canonical: type.canonical + }), + (workInProgress.stateNode = type), + current + ? (workInProgress.flags |= 4) + : appendAllChildren(type, workInProgress, !1, !1)); + } +}; +updateHostText = function(current, workInProgress, oldText, newText) { + oldText !== newText + ? ((current = requiredContext(rootInstanceStackCursor.current)), + (oldText = requiredContext(contextStackCursor$1.current)), + (workInProgress.stateNode = createTextInstance( + newText, + current, + oldText, + workInProgress + )), + (workInProgress.flags |= 4)) + : (workInProgress.stateNode = current.stateNode); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$40 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$40 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$40 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$40.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$42 = completedWork.selfBaseDuration, + child$43 = completedWork.child; + null !== child$43; + + ) + (newChildLanes |= child$43.lanes | child$43.childLanes), + (subtreeFlags |= child$43.subtreeFlags & 1835008), + (subtreeFlags |= child$43.flags & 1835008), + (treeBaseDuration$42 += child$43.treeBaseDuration), + (child$43 = child$43.sibling); + completedWork.treeBaseDuration = treeBaseDuration$42; + } else + for ( + treeBaseDuration$42 = completedWork.child; + null !== treeBaseDuration$42; + + ) + (newChildLanes |= + treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes), + (subtreeFlags |= treeBaseDuration$42.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$42.flags & 1835008), + (treeBaseDuration$42.return = completedWork), + (treeBaseDuration$42 = treeBaseDuration$42.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$42 = completedWork.actualDuration; + child$43 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$42 += child.actualDuration), + (child$43 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$42; + completedWork.treeBaseDuration = child$43; + } else + for ( + treeBaseDuration$42 = completedWork.child; + null !== treeBaseDuration$42; + + ) + (newChildLanes |= + treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes), + (subtreeFlags |= treeBaseDuration$42.subtreeFlags), + (subtreeFlags |= treeBaseDuration$42.flags), + (treeBaseDuration$42.return = completedWork), + (treeBaseDuration$42 = treeBaseDuration$42.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeSuspendedOffscreenHostContainer(current, workInProgress) { + var rootContainerInstance = requiredContext(rootInstanceStackCursor.current), + type = workInProgress.type, + newProps = workInProgress.memoizedProps; + null !== current + ? updateHostComponent( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) + : ((current = requiredContext(contextStackCursor$1.current)), + (rootContainerInstance = createInstance( + type, + newProps, + rootContainerInstance, + current, + workInProgress + )), + appendAllChildren(rootContainerInstance, workInProgress, !1, !1), + (workInProgress.stateNode = rootContainerInstance), + null !== workInProgress.ref && (workInProgress.flags |= 256)); + bubbleProperties(workInProgress); +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (newProps = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + newProps.pendingContext && + ((newProps.context = newProps.pendingContext), + (newProps.pendingContext = null)), + (null !== current && null !== current.child) || + newProps.hydrate || + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + current = requiredContext(contextStackCursor$1.current); + current = createInstance( + type, + newProps, + renderLanes, + current, + workInProgress + ); + appendAllChildren(current, workInProgress, !1, !1); + workInProgress.stateNode = current; + null !== workInProgress.ref && (workInProgress.flags |= 256); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + renderLanes = requiredContext(contextStackCursor$1.current); + workInProgress.stateNode = createTextInstance( + newProps, + current, + renderLanes, + workInProgress + ); + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.flags & 128)) + return ( + (workInProgress.lanes = renderLanes), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress + ); + newProps = null !== newProps; + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if ( + newProps && + !renderLanes && + ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) + ) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3); + else { + if ( + 0 === workInProgressRootExitStatus || + 3 === workInProgressRootExitStatus + ) + workInProgressRootExitStatus = 4; + null === workInProgressRoot || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || + markRootSuspended$1( + workInProgressRoot, + workInProgressRootRenderLanes + ); + } + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + var renderedTail = type.rendering; + if (null === renderedTail) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + renderedTail = findFirstSuspended(current); + if (null !== renderedTail) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = renderedTail.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (newProps = workInProgress.child; null !== newProps; ) + (renderLanes = newProps), + (renderedTail = current), + (renderLanes.flags &= 1835010), + (type = renderLanes.alternate), + null === type + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = renderedTail), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null), + (renderLanes.selfBaseDuration = 0), + (renderLanes.treeBaseDuration = 0)) + : ((renderLanes.childLanes = type.childLanes), + (renderLanes.lanes = type.lanes), + (renderLanes.child = type.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = type.memoizedProps), + (renderLanes.memoizedState = type.memoizedState), + (renderLanes.updateQueue = type.updateQueue), + (renderLanes.type = type.type), + (renderedTail = type.dependencies), + (renderLanes.dependencies = + null === renderedTail + ? null + : { + lanes: renderedTail.lanes, + firstContext: renderedTail.firstContext + }), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(renderedTail)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !renderedTail.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((renderedTail.sibling = workInProgress.child), + (workInProgress.child = renderedTail)) + : ((current = type.last), + null !== current + ? (current.sibling = renderedTail) + : (workInProgress.child = renderedTail), + (type.last = renderedTail)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + "unstable-defer-without-hiding" !== newProps.mode && + 23 !== workInProgress.tag && + (workInProgress.flags |= 4096), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + bubbleProperties(workInProgress) + : bubbleProperties(workInProgress), + null + ); + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + didReceiveUpdate = !1; +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + workInProgress.child = + null === current + ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) + : reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); +} +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + Component = Component.render; + var ref = workInProgress.ref; + prepareToReadContext(workInProgress, renderLanes); + nextProps = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + ref, + renderLanes + ); + if (null !== current && !didReceiveUpdate) + return ( + (workInProgress.updateQueue = current.updateQueue), + (workInProgress.flags &= -1029), + (current.lanes &= ~renderLanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + workInProgress.flags |= 1; + reconcileChildren(current, workInProgress, nextProps, renderLanes); + return workInProgress.child; +} +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if (null === current) { + var type = Component.type; + if ( + "function" === typeof type && + !shouldConstruct(type) && + void 0 === type.defaultProps && + null === Component.compare && + void 0 === Component.defaultProps + ) + return ( + (workInProgress.tag = 15), + (workInProgress.type = type), + updateSimpleMemoComponent( + current, + workInProgress, + type, + nextProps, + renderLanes + ) + ); + current = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); + } + type = current.child; + if (0 === (current.lanes & renderLanes)) { + var prevProps = type.memoizedProps; + Component = Component.compare; + Component = null !== Component ? Component : shallowEqual; + if (Component(prevProps, nextProps) && current.ref === workInProgress.ref) + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + workInProgress.flags |= 1; + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); +} +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if ( + null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref + ) + if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps, + nextChildren = nextProps.children, + prevState = null !== current ? current.memoizedState : null; + if ( + "hidden" === nextProps.mode || + "unstable-defer-without-hiding" === nextProps.mode + ) + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + prevState = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= prevState; + } + else + null !== prevState + ? ((prevState = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) - : (nextProps = renderLanes), + : (prevState = renderLanes), push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + (subtreeRenderLanes |= prevState); + if (enablePersistentOffscreenHostContainer) + return reconcileOffscreenHostContainer( + current, + workInProgress, + "hidden" === nextProps.mode && 23 !== workInProgress.tag, + nextChildren, + renderLanes + ); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { +function reconcileOffscreenHostContainer( + currentOffscreen, + offscreen, + isHidden, + children, + renderLanes +) { + isHidden = getOffscreenContainerProps( + isHidden ? "hidden" : "visible", + children + ); + null === currentOffscreen + ? (renderLanes = createOffscreenHostContainerFiber( + isHidden, + offscreen.mode, + renderLanes, + null + )) + : ((currentOffscreen = currentOffscreen.child), + null === currentOffscreen + ? ((renderLanes = createOffscreenHostContainerFiber( + isHidden, + offscreen.mode, + renderLanes, + null + )), + (renderLanes.flags |= 2)) + : (renderLanes = createWorkInProgress(currentOffscreen, isHidden))); + renderLanes.return = offscreen; + return (offscreen.child = renderLanes); +} +function markRef$1(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4590,7 +5248,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef(current, workInProgress); + markRef$1(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -4693,7 +5351,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes = createFiberFromOffscreen( { mode: "visible", children: current }, workInProgress.mode, - renderLanes, + 0, null ); renderLanes.return = workInProgress; @@ -4826,22 +5484,56 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child, + currentFallbackChildFragment = currentPrimaryChildFragment.sibling, primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), + 0 === (mode & 1) && workInProgress.child !== currentPrimaryChildFragment + ? ((current = workInProgress.child), + (current.childLanes = 0), + (current.pendingProps = primaryChildProps), workInProgress.mode & 2 && - ((primaryChildren.actualDuration = 0), - (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = current.selfBaseDuration), - (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + ((current.actualDuration = 0), + (current.actualStartTime = -1), + (current.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration), + (current.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration)), + enablePersistentOffscreenHostContainer && + ((currentPrimaryChildFragment = currentPrimaryChildFragment.child), + (primaryChildProps = current.child), + (primaryChildren = getOffscreenContainerProps( + "hidden", + primaryChildren + )), + (primaryChildProps.pendingProps = primaryChildren), + (primaryChildProps.memoizedProps = primaryChildren), + completeSuspendedOffscreenHostContainer( + currentPrimaryChildFragment, + primaryChildProps + )), (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + : ((current = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )), + enablePersistentOffscreenHostContainer && + ((primaryChildProps = currentPrimaryChildFragment.child), + null !== primaryChildProps && + ((primaryChildren = reconcileOffscreenHostContainer( + currentPrimaryChildFragment, + current, + !0, + primaryChildren, + renderLanes + )), + (primaryChildren.memoizedProps = primaryChildren.pendingProps), + completeSuspendedOffscreenHostContainer( + primaryChildProps, + primaryChildren + ))), + (current.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & 1835008)); null !== currentFallbackChildFragment ? (fallbackChildren = createWorkInProgress( currentFallbackChildFragment, @@ -4855,9 +5547,9 @@ function updateSuspenseFallbackChildren( )), (fallbackChildren.flags |= 2)); fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; + current.return = workInProgress; + current.sibling = fallbackChildren; + workInProgress.child = current; return fallbackChildren; } function scheduleWorkOnFiber(fiber, renderLanes) { @@ -4953,613 +5645,124 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { current = revealOrder.alternate; if (null !== current && null === findFirstSuspended(current)) { workInProgress.child = revealOrder; - break; - } - current = revealOrder.sibling; - revealOrder.sibling = renderLanes; - renderLanes = revealOrder; - revealOrder = current; - } - initSuspenseListRenderState( - workInProgress, - !0, - renderLanes, - null, - tailMode - ); - break; - case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); - break; - default: - workInProgress.memoizedState = null; - } - return workInProgress.child; -} -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - null !== current && (workInProgress.dependencies = current.dependencies); - profilerStartTime = -1; - workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 === (renderLanes & workInProgress.childLanes)) return null; - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( - current, - current.pendingProps - )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; - } - return workInProgress.child; -} -function hadNoMutationsEffects(current, completedWork) { - if (null !== current && current.child === completedWork.child) return !0; - if (0 !== (completedWork.flags & 16)) return !1; - for (current = completedWork.child; null !== current; ) { - if (0 !== (current.flags & 6454) || 0 !== (current.subtreeFlags & 6454)) - return !1; - current = current.sibling; - } - return !0; -} -var appendAllChildren, - updateHostContainer, - updateHostComponent$1, - updateHostText$1; -appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNode(parent.node, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNode(parent.node, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildren(parent, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -function appendAllChildrenToContainer( - containerChildSet, - workInProgress, - needsVisibilityToggle, - isHidden -) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag) { - var instance = node.stateNode; - needsVisibilityToggle && - isHidden && - (instance = cloneHiddenInstance(instance)); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (6 === node.tag) { - instance = node.stateNode; - if (needsVisibilityToggle && isHidden) - throw Error("Not yet implemented."); - appendChildNodeToSet(containerChildSet, instance.node); - } else if (4 !== node.tag) - if (22 === node.tag && null !== node.memoizedState) - (instance = node.child), - null !== instance && (instance.return = node), - appendAllChildrenToContainer(containerChildSet, node, !0, !0); - else if (null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; + break; + } + current = revealOrder.sibling; + revealOrder.sibling = renderLanes; + renderLanes = revealOrder; + revealOrder = current; + } + initSuspenseListRenderState( + workInProgress, + !0, + renderLanes, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; } - node.sibling.return = node.return; - node = node.sibling; - } + return workInProgress.child; } -updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); - appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); - portalOrRoot.pendingChildren = newChildSet; - workInProgress.flags |= 4; - completeRoot(current, newChildSet); - } -}; -updateHostComponent$1 = function(current, workInProgress, type, newProps) { - type = current.stateNode; - var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) - workInProgress.stateNode = type; - else { - var recyclableInstance = workInProgress.stateNode; - requiredContext(contextStackCursor$1.current); - var updatePayload = null; - oldProps !== newProps && - ((oldProps = diffProperties( - null, - oldProps, - newProps, - recyclableInstance.canonical.viewConfig.validAttributes - )), - (recyclableInstance.canonical.currentProps = newProps), - (updatePayload = oldProps)); - current && null === updatePayload - ? (workInProgress.stateNode = type) - : ((newProps = updatePayload), - (oldProps = type.node), - (type = { - node: current - ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) - : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), - canonical: type.canonical - }), - (workInProgress.stateNode = type), - current - ? (workInProgress.flags |= 4) - : appendAllChildren(type, workInProgress, !1, !1)); - } -}; -updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText - ? ((current = requiredContext(rootInstanceStackCursor.current)), - (oldText = requiredContext(contextStackCursor$1.current)), - (workInProgress.stateNode = createTextInstance( - newText, - current, - oldText, - workInProgress - )), - (workInProgress.flags |= 4)) - : (workInProgress.stateNode = current.stateNode); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$72 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$72 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$72 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$72.sibling = null); +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + null !== current && (workInProgress.dependencies = current.dependencies); + profilerStartTime = -1; + workInProgressRootSkippedLanes |= workInProgress.lanes; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; } + return workInProgress.child; } -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - if (0 !== (completedWork.mode & 2)) { - for ( - var treeBaseDuration$74 = completedWork.selfBaseDuration, - child$75 = completedWork.child; - null !== child$75; - - ) - (newChildLanes |= child$75.lanes | child$75.childLanes), - (subtreeFlags |= child$75.subtreeFlags & 1835008), - (subtreeFlags |= child$75.flags & 1835008), - (treeBaseDuration$74 += child$75.treeBaseDuration), - (child$75 = child$75.sibling); - completedWork.treeBaseDuration = treeBaseDuration$74; - } else - for ( - treeBaseDuration$74 = completedWork.child; - null !== treeBaseDuration$74; - - ) - (newChildLanes |= - treeBaseDuration$74.lanes | treeBaseDuration$74.childLanes), - (subtreeFlags |= treeBaseDuration$74.subtreeFlags & 1835008), - (subtreeFlags |= treeBaseDuration$74.flags & 1835008), - (treeBaseDuration$74.return = completedWork), - (treeBaseDuration$74 = treeBaseDuration$74.sibling); - else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$74 = completedWork.actualDuration; - child$75 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$74 += child.actualDuration), - (child$75 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$74; - completedWork.treeBaseDuration = child$75; - } else - for ( - treeBaseDuration$74 = completedWork.child; - null !== treeBaseDuration$74; - - ) - (newChildLanes |= - treeBaseDuration$74.lanes | treeBaseDuration$74.childLanes), - (subtreeFlags |= treeBaseDuration$74.subtreeFlags), - (subtreeFlags |= treeBaseDuration$74.flags), - (treeBaseDuration$74.return = completedWork), - (treeBaseDuration$74 = treeBaseDuration$74.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; +function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes +) { switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + pushHostRootContext(workInProgress); + break; case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = nextReactTag; - nextReactTag += 2; - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - renderLanes = createNode( - current, - type.uiViewClassName, - renderLanes, - updatePayload, - workInProgress - ); - current = new ReactFabricHostComponent( - current, - type, - newProps, - workInProgress - ); - current = { node: renderLanes, canonical: current }; - appendAllChildren(current, workInProgress, !1, !1); - workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 256); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - renderLanes = requiredContext(contextStackCursor$1.current); - workInProgress.stateNode = createTextInstance( - newProps, + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; + case 10: + var context = workInProgress.type._context, + nextValue = workInProgress.memoizedProps.value; + push(valueCursor, context._currentValue2); + context._currentValue2 = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + context = workInProgress.stateNode; + context.effectDuration = 0; + context.passiveEffectDuration = 0; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent(current, workInProgress, renderLanes); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + current = bailoutOnAlreadyFinishedWork( current, - renderLanes, - workInProgress + workInProgress, + renderLanes ); + return null !== current ? current.sibling : null; } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress - ); - newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if ( - newProps && - !renderLanes && - ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) - ) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3); - else { - if ( - 0 === workInProgressRootExitStatus || - 3 === workInProgressRootExitStatus - ) - workInProgressRootExitStatus = 4; - null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || - markRootSuspended$1( - workInProgressRoot, - workInProgressRootRenderLanes - ); - } - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (updatePayload = current), - (renderLanes.flags &= 1835010), - (type = renderLanes.alternate), - null === type - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = updatePayload), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null), - (renderLanes.selfBaseDuration = 0), - (renderLanes.treeBaseDuration = 0)) - : ((renderLanes.childLanes = type.childLanes), - (renderLanes.lanes = type.lanes), - (renderLanes.child = type.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = - null === updatePayload - ? null - : { - lanes: updatePayload.lanes, - firstContext: updatePayload.firstContext - }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + context = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (context) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (context) break; + else return null; case 22: case 23: return ( - popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== renderLanes && - "unstable-defer-without-hiding" !== newProps.mode && - 23 !== workInProgress.tag && - (workInProgress.flags |= 4096), - renderLanes && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - bubbleProperties(workInProgress) - : bubbleProperties(workInProgress), - null + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5728,8 +5931,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$88 = effect.create; - effect.destroy = create$88(); + var create$89 = effect.create; + effect.destroy = create$89(); } effect = effect.next; } while (effect !== finishedWork); @@ -5944,8 +6147,8 @@ function commitMutationEffects(root, firstChild, committedLanes) { switch (root.tag) { case 13: if (null !== root.memoizedState) { - var current$94 = root.alternate; - if (null === current$94 || null === current$94.memoizedState) + var current$95 = root.alternate; + if (null === current$95 || null === current$95.memoizedState) globalMostRecentFallbackTime = now(); } } @@ -6055,22 +6258,22 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { commitUpdateQueue(committedLanes, updateQueue, instance); break; case 3: - var updateQueue$90 = committedLanes.updateQueue; - if (null !== updateQueue$90) { - var instance$91 = null; + var updateQueue$91 = committedLanes.updateQueue; + if (null !== updateQueue$91) { + var instance$92 = null; if (null !== committedLanes.child) switch (committedLanes.child.tag) { case 5: - instance$91 = + instance$92 = committedLanes.child.stateNode.canonical; break; case 1: - instance$91 = committedLanes.child.stateNode; + instance$92 = committedLanes.child.stateNode; } commitUpdateQueue( committedLanes, - updateQueue$90, - instance$91 + updateQueue$91, + instance$92 ); } break; @@ -6086,7 +6289,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender, effectDuration = committedLanes.stateNode.effectDuration; - instance$91 = commitTime; + instance$92 = commitTime; current = null === current ? "mount" : "update"; currentUpdateIsNested && (current = "nested-update"); "function" === typeof onRender && @@ -6096,14 +6299,14 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { committedLanes.actualDuration, committedLanes.treeBaseDuration, committedLanes.actualStartTime, - instance$91 + instance$92 ); "function" === typeof onCommit && onCommit( committedLanes.memoizedProps.id, current, effectDuration, - instance$91 + instance$92 ); enqueuePendingPassiveProfilerEffect(committedLanes); var parentFiber = committedLanes.return; @@ -6133,27 +6336,27 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { ); } if (committedLanes.flags & 256) { - instance$91 = void 0; + instance$92 = void 0; current = committedLanes; var ref = current.ref; if (null !== ref) { var instance$jscomp$0 = current.stateNode; switch (current.tag) { case 5: - instance$91 = instance$jscomp$0.canonical; + instance$92 = instance$jscomp$0.canonical; break; default: - instance$91 = instance$jscomp$0; + instance$92 = instance$jscomp$0; } if ("function" === typeof ref) if (current.mode & 2) try { - startLayoutEffectTimer(), ref(instance$91); + startLayoutEffectTimer(), ref(instance$92); } finally { recordLayoutEffectDuration(current); } - else ref(instance$91); - else ref.current = instance$91; + else ref(instance$92); + else ref.current = instance$92; } } } catch (error) { @@ -6168,10 +6371,10 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { nextEffect = null; break; } - instance$91 = committedLanes.sibling; - if (null !== instance$91) { - instance$91.return = committedLanes.return; - nextEffect = instance$91; + instance$92 = committedLanes.sibling; + if (null !== instance$92) { + instance$92.return = committedLanes.return; + nextEffect = instance$92; break; } nextEffect = committedLanes.return; @@ -6705,6 +6908,20 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress$32.flags |= 128; sourceFiber.flags |= 32768; sourceFiber.flags &= -10053; + if ( + enablePersistentOffscreenHostContainer && + null === workInProgress$32.alternate + ) { + var offscreenContainer = workInProgress$32.child.child; + if (null !== offscreenContainer) { + var containerProps = getOffscreenContainerProps( + "hidden", + offscreenContainer.memoizedProps.children + ); + offscreenContainer.pendingProps = containerProps; + offscreenContainer.memoizedProps = containerProps; + } + } if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -7296,7 +7513,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; if (null !== current) if ( current.memoizedProps !== workInProgress.pendingProps || @@ -7304,165 +7520,98 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ) didReceiveUpdate = !0; else { - if (0 === (renderLanes & updateLanes)) { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.type._context; - var nextValue = workInProgress.memoizedProps.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = nextValue; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (updateLanes) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; - } - nextValue = workInProgress.memoizedState; - null !== nextValue && - ((nextValue.rendering = null), - (nextValue.tail = null), - (nextValue.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes + if ( + 0 === (current.lanes & renderLanes) && + 0 === (workInProgress.flags & 128) + ) + return ( + (didReceiveUpdate = !1), + attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) ); - } didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { case 2: - updateLanes = workInProgress.type; + var Component = workInProgress.type; null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + var context = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, - updateLanes, + Component, current, - nextValue, + context, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof nextValue && - null !== nextValue && - "function" === typeof nextValue.render && - void 0 === nextValue.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; workInProgress.updateQueue = null; - if (isContextProvider(updateLanes)) { + if (isContextProvider(Component)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== nextValue.state && void 0 !== nextValue.state - ? nextValue.state + null !== context.state && void 0 !== context.state + ? context.state : null; initializeUpdateQueue(workInProgress); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; - mountClassInstance(workInProgress, updateLanes, current, renderLanes); + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; + mountClassInstance(workInProgress, Component, current, renderLanes); workInProgress = finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, hasContext, renderLanes ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, nextValue, renderLanes), + reconcileChildren(null, workInProgress, context, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - nextValue = workInProgress.elementType; + Component = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = nextValue._init; - nextValue = hasContext(nextValue._payload); - workInProgress.type = nextValue; - hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); - current = resolveDefaultProps(nextValue, current); - switch (hasContext) { + context = Component._init; + Component = context(Component._payload); + workInProgress.type = Component; + context = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (context) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7471,7 +7620,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7480,7 +7629,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7489,79 +7638,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), - updateLanes, + Component, + resolveDefaultProps(Component.type, current), renderLanes ); break a; } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + Component + ". Lazy element type must resolve to a class or function." ); } return workInProgress; case 0: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateFunctionComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 1: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateClassComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 3: pushHostRootContext(workInProgress); - updateLanes = workInProgress.updateQueue; - if (null === current || null === updateLanes) + Component = workInProgress.updateQueue; + if (null === current || null === Component) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - nextValue = workInProgress.pendingProps; - updateLanes = workInProgress.memoizedState.element; + context = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, context, null, renderLanes); + context = workInProgress.memoizedState.element; + context === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, context, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: return ( pushHostContext(workInProgress), - (updateLanes = workInProgress.pendingProps.children), - markRef(current, workInProgress), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + (Component = workInProgress.pendingProps.children), + markRef$1(current, workInProgress), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -7574,35 +7722,30 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (updateLanes = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - updateLanes, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - updateLanes, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateForwardRef( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); @@ -7629,9 +7772,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (updateLanes = workInProgress.stateNode), - (updateLanes.effectDuration = 0), - (updateLanes.passiveEffectDuration = 0), + (Component = workInProgress.stateNode), + (Component.effectDuration = 0), + (Component.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -7642,16 +7785,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); case 10: a: { - updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + Component = workInProgress.type._context; + context = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - var newValue = nextValue.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = newValue; + var newValue = context.value; + push(valueCursor, Component._currentValue2); + Component._currentValue2 = newValue; if (null !== hasContext) if (objectIs(hasContext.value, newValue)) { if ( - hasContext.children === nextValue.children && + hasContext.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7676,7 +7819,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { null !== dependency; ) { - if (dependency.context === updateLanes) { + if (dependency.context === Component) { if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; @@ -7727,7 +7870,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7735,29 +7878,25 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), - (updateLanes = workInProgress.pendingProps.children), + (context = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context)), + (Component = Component(context)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), - (hasContext = resolveDefaultProps( - nextValue, - workInProgress.pendingProps - )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (Component = workInProgress.type), + (context = resolveDefaultProps(Component, workInProgress.pendingProps)), + (context = resolveDefaultProps(Component.type, context)), updateMemoComponent( current, workInProgress, - nextValue, - hasContext, - updateLanes, + Component, + context, renderLanes ) ); @@ -7767,32 +7906,31 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.type, workInProgress.pendingProps, - updateLanes, renderLanes ); case 17: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)), (workInProgress.tag = 1), - isContextProvider(updateLanes) + isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, Component, context), + mountClassInstance(workInProgress, Component, context, renderLanes), finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, current, renderLanes @@ -7981,6 +8119,13 @@ function createFiberFromTypeAndProps( key.lanes = lanes; return key; } +function createOffscreenHostContainerFiber(props, fiberMode, lanes, key) { + props = createFiber(5, props, key, fiberMode); + props.elementType = "RCTView"; + props.type = "RCTView"; + props.lanes = lanes; + return props; +} function createFiberFromFragment(elements, mode, lanes, key) { elements = createFiber(7, elements, key, mode); elements.lanes = lanes; @@ -8232,10 +8377,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_979 = { + devToolsConfig$jscomp$inline_978 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "18.0.0-419cc9c37-20210726", + version: "18.0.0-19092ac8c-20210803", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8250,11 +8395,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1236 = { - bundleType: devToolsConfig$jscomp$inline_979.bundleType, - version: devToolsConfig$jscomp$inline_979.version, - rendererPackageName: devToolsConfig$jscomp$inline_979.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_979.rendererConfig, +var internals$jscomp$inline_1239 = { + bundleType: devToolsConfig$jscomp$inline_978.bundleType, + version: devToolsConfig$jscomp$inline_978.version, + rendererPackageName: devToolsConfig$jscomp$inline_978.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_978.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8270,26 +8415,26 @@ var internals$jscomp$inline_1236 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_979.findFiberByHostInstance || + devToolsConfig$jscomp$inline_978.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-419cc9c37-20210726" + reconcilerVersion: "18.0.0-19092ac8c-20210803" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1237 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1240 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1237.isDisabled && - hook$jscomp$inline_1237.supportsFiber + !hook$jscomp$inline_1240.isDisabled && + hook$jscomp$inline_1240.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1237.inject( - internals$jscomp$inline_1236 + (rendererID = hook$jscomp$inline_1240.inject( + internals$jscomp$inline_1239 )), - (injectedHook = hook$jscomp$inline_1237); + (injectedHook = hook$jscomp$inline_1240); } catch (err) {} } exports.createPortal = function(children, containerTag) { diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 9d63f703e0da4d..edd92aea646055 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ 'use strict'; @@ -19,6 +19,7 @@ if (__DEV__) { var React = require("react"); require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"); +var dynamicFlags = require("ReactNativeInternalFeatureFlags"); var Scheduler = require("scheduler"); var ReactSharedInternals = @@ -3126,7 +3127,11 @@ function getComponentNameFromFiber(fiber) { return null; } -// The rest of the flags are static for better dead code elimination. +// Re-export dynamic flags from the internal module. Intentionally using * +// the exports object every time a flag is read. + +var enablePersistentOffscreenHostContainer = + dynamicFlags.enablePersistentOffscreenHostContainer; // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; var enableProfilerCommitHooks = true; var enableLazyElements = false; @@ -5027,16 +5032,29 @@ function lanesToEventPriority(lanes) { // can re-export everything from this module. function shim() { + { + throw Error( + "The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue." + ); + } +} // Persistence (when unsupported) + +var supportsPersistence = false; +var getOffscreenContainerProps = shim; + +// can re-export everything from this module. + +function shim$1() { { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } } // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; -var errorHydratingContainer = shim; +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; +var errorHydratingContainer = shim$1; var getViewConfigForType = ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; @@ -6131,7 +6149,7 @@ var Passive$1 = /* */ 4; -var ReactVersion = "18.0.0-419cc9c37-20210726"; +var ReactVersion = "18.0.0-19092ac8c-20210803"; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -13124,7 +13142,9 @@ function throwException( // ensure that new initial loading states can commit as soon as possible. attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; + _workInProgress.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in + // the begin phase to prevent an early bailout. + _workInProgress.lanes = rootRenderLanes; return; } // This boundary already captured during this render. Continue to the next @@ -13199,3676 +13219,3835 @@ function throwException( } while (workInProgress !== null); } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; - -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; } -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - if (current === null) { - // If this is a fresh new component that hasn't been rendered yet, we - // won't update its child set by applying minimal side-effects. Instead, - // we will add them all to the child before it gets rendered. That means - // we can optimize this reconciliation pass by not tracking side-effects. - workInProgress.child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - } else { - // If the current child is the same as the work in progress, it means that - // we haven't yet started any work on these children. Therefore, we use - // the clone algorithm to create a copy of all the current children. - // If we had any progressed work already, that is invalid at this point so - // let's throw it out. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); - } +function markRef(workInProgress) { + workInProgress.flags |= Ref; } -function forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes -) { - // This function is fork of reconcileChildren. It's used in cases where we - // want to reconcile without matching against the existing set. This has the - // effect of all current children being unmounted; even if the type and key - // are the same, the old child is unmounted and a new child is created. - // - // To do this, we're going to go through the reconcile algorithm twice. In - // the first pass, we schedule a deletion for all the current children by - // passing null. - workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - ); // In the second pass, we mount the new children. The trick here is that we - // pass null in place of where we usually pass the current child set. This has - // the effect of remounting all children regardless of whether their - // identities match. +var appendAllChildren; +var updateHostContainer; +var updateHostComponent; +var updateHostText; - workInProgress.child = reconcileChildFibers( +{ + // Mutation mode + appendAllChildren = function( + parent, workInProgress, - null, - nextChildren, - renderLanes - ); -} - -function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens after the first render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + needsVisibilityToggle, + isHidden + ) { + // We only have the top Fiber that was created but we need recurse down its + // children to find all the terminal nodes. + var node = workInProgress.child; - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); + while (node !== null) { + if (node.tag === HostComponent || node.tag === HostText) { + appendInitialChild(parent, node.stateNode); + } else if (node.tag === HostPortal); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - } - } - - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); + if (node === workInProgress) { + return; + } - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); - } finally { - reenableLogs(); + node = node.return; } - } - setIsRendering(false); - } + node.sibling.return = node.return; + node = node.sibling; + } + }; - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + updateHostContainer = function(current, workInProgress) { + // Noop + }; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + updateHostComponent = function( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ) { + // If we have an alternate, that means this is an update and we need to + // schedule a side-effect to do the updates. + var oldProps = current.memoizedProps; -function updateMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - if (current === null) { - var type = Component.type; + if (oldProps === newProps) { + // In mutation mode, this is sufficient for a bailout because + // we won't touch this node even if children changed. + return; + } // If we get updated because one of our children updated, we don't + // have newProps so we'll have to reuse them. + // TODO: Split the update API as separate for the props vs. children. + // Even better would be if children weren't special cased at all tho. - if ( - isSimpleFunctionComponent(type) && - Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. - Component.defaultProps === undefined - ) { - var resolvedType = type; + var instance = workInProgress.stateNode; + var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host + // component is hitting the resume path. Figure out why. Possibly + // related to `hidden`. - { - resolvedType = resolveFunctionForHotReloading(type); - } // If this is a plain function component without default props, - // and with only the default shallow comparison, we upgrade it - // to a SimpleMemoComponent to allow fast path updates. + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; + workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there + // is a new ref we mark this as an update. All the work is done in commitWork. - { - validateFunctionComponentInDev(workInProgress, type); - } + if (updatePayload) { + markUpdate(workInProgress); + } + }; - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); + updateHostText = function(current, workInProgress, oldText, newText) { + // If the text differs, mark it as an update. All the work in done in commitWork. + if (oldText !== newText) { + markUpdate(workInProgress); } + }; +} - { - var innerPropTypes = type.propTypes; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var tailNode = renderState.tail; + var lastTailNode = null; - if (innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(type) - ); + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } + + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (lastTailNode === null) { + // All remaining items in the tail are insertions. + renderState.tail = null; + } else { + // Detach the insertion after the last node that was already + // inserted. + lastTailNode.sibling = null; } + + break; } - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; - } + case "collapsed": { + // Any insertions at the end of the tail list after this point + // should be invisible. If there are already mounted boundaries + // anything before them are not considered for collapsing. + // Therefore we need to go through the whole tail to find if + // there are any. + var _tailNode = renderState.tail; + var _lastTailNode = null; - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } - if (_innerPropTypes) { - // Inner memo component props aren't currently validated in createElement. - // We could move it there, but we'd still need this for lazy code path. - checkPropTypes( - _innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(_type) - ); + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. + + if (_lastTailNode === null) { + // All remaining items in the tail are insertions. + if (!hasRenderedATailFallback && renderState.tail !== null) { + // We suspended during the head. We want to show at least one + // row at the tail. So we'll keep on and cut off the rest. + renderState.tail.sibling = null; + } else { + renderState.tail = null; + } + } else { + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; + } + + break; } } +} - var currentChild = current.child; // This is always exactly one child +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - if (!includesSomeLane(updateLanes, renderLanes)) { - // This will be the props with resolved defaultProps, - // unlike current.memoizedProps which will be the unresolved ones. - var prevProps = currentChild.memoizedProps; // Default to shallow comparison + if (!didBailout) { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var actualDuration = completedWork.actualDuration; + var treeBaseDuration = completedWork.selfBaseDuration; + var child = completedWork.child; - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + subtreeFlags |= child.subtreeFlags; + subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will + // only be updated if work is done on the fiber (i.e. it doesn't bailout). + // When work is done, it should bubble to the parent's actualDuration. If + // the fiber has not been cloned though, (meaning no work was done), then + // this value will reflect the amount of time spent working on a previous + // render. In that case it should not bubble. We determine whether it was + // cloned by comparing the child pointer. - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + subtreeFlags |= _child.subtreeFlags; + subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child.return = completedWork; + _child = _child.sibling; + } } - } // React DevTools reads this flag. - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} + completedWork.subtreeFlags |= subtreeFlags; + } else { + // Bubble up the earliest expiration time. + if ((completedWork.mode & ProfileMode) !== NoMode) { + // In profiling mode, resetChildExpirationTime is also used to reset + // profiler durations. + var _treeBaseDuration = completedWork.selfBaseDuration; + var _child2 = completedWork.child; -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - // TODO: current can be non-null here even if the component - // hasn't yet mounted. This happens when the inner render suspends. - // We'll need to figure out if this is fine or can cause issues. - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var outerMemoType = workInProgress.elementType; + while (_child2 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child2.lanes, _child2.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. - if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { - // We warn when you define propTypes on lazy() - // so let's just skip over it to find memo() outer wrapper. - // Inner props for memo are validated later. - var lazyComponent = outerMemoType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + while (_child3 !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child3.lanes, _child3.childLanes) + ); // "Static" flags share the lifetime of the fiber/hook they belong to, + // so we should bubble those up even during a bailout. All the other + // flags have a lifetime only of a single render + commit, so we should + // ignore them. - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentNameFromType(outerMemoType) - ); - } + subtreeFlags |= _child3.subtreeFlags & StaticMask; + subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code + // smell because it assumes the commit phase is never concurrent with + // the render phase. Will address during refactor to alternate model. + + _child3.return = completedWork; + _child3 = _child3.sibling; } } + + completedWork.subtreeFlags |= subtreeFlags; } - if (current !== null) { - var prevProps = current.memoizedProps; + completedWork.childLanes = newChildLanes; + return didBailout; +} - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; +function completeSuspendedOffscreenHostContainer(current, workInProgress) { + // This is a fork of the complete phase for HostComponent. We use it when + // a suspense tree is in its fallback state, because in that case the primary + // tree that includes the offscreen boundary is skipped over without a + // regular complete phase. + // + // We can optimize this path further by inlining the update logic for + // offscreen instances specifically, i.e. skipping the `prepareUpdate` call. + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + var newProps = workInProgress.memoizedProps; - if (!includesSomeLane(renderLanes, updateLanes)) { - // The pending lanes were cleared at the beginning of beginWork. We're - // about to bail out, but there might be other lanes that weren't - // included in the current render. Usually, the priority level of the - // remaining updates is accumulated during the evaluation of the - // component (i.e. when processing the update queue). But since since - // we're bailing out early *without* evaluating the component, we need - // to account for it here, too. Reset to the value of the current fiber. - // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, - // because a MemoComponent fiber does not have hooks or an update queue; - // rather, it wraps around an inner component, which may or may not - // contains hooks. - // TODO: Move the reset at in beginWork out of the common path so that - // this is no longer necessary. - workInProgress.lanes = current.lanes; - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } + if (current !== null) { + updateHostComponent( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + } else { + var currentHostContext = getHostContext(); + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. + + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef(workInProgress); } } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); + bubbleProperties(workInProgress); } -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the - // previous render. We will push this to the cache pool context so that we can - // resume in-flight requests. - - var spawnedCachePool = null; - - if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" - ) { - // Rendering a hidden tree. - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - var nextState = { - baseLanes: NoLanes, - cachePool: null - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - // We're hidden, and we're not rendering at Offscreen. We will bail out - // and resume this tree later. - var nextBaseLanes; - - if (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. - - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes, - cachePool: spawnedCachePool - }; - workInProgress.memoizedState = _nextState; - workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. - - pushRenderLanes(workInProgress, nextBaseLanes); +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); return null; - } else { - var _nextState2 = { - baseLanes: NoLanes, - cachePool: null - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } - } else { - // Rendering a visible tree. - var _subtreeRenderLanes; + case ClassComponent: { + var Component = workInProgress.type; - if (prevState !== null) { - // We're going from hidden -> visible. - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); + if (isContextProvider(Component)) { + popContext(workInProgress); + } - workInProgress.memoizedState = null; - } else { - // We weren't previously hidden, and we still aren't, so there's nothing - // special to do. Need to push to the stack regardless, though, to avoid - // a push/pop misalignment. - _subtreeRenderLanes = renderLanes; + bubbleProperties(workInProgress); + return null; } - pushRenderLanes(workInProgress, _subtreeRenderLanes); - } - - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} // Note: These happen to have identical begin phases, for now. We shouldn't hold -// ourselves to this constraint, though. If the behavior diverges, we should -// fork the function. + case HostRoot: { + var fiberRoot = workInProgress.stateNode; -var updateLegacyHiddenComponent = updateOffscreenComponent; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (current === null || current.child === null) { + // If we hydrated, pop so that we can delete any remaining children + // that weren't hydrated. + var wasHydrated = popHydrationState(); -function updateProfiler(current, workInProgress, renderLanes) { - { - workInProgress.flags |= Update; + if (wasHydrated) { + // If we hydrated, then we'll need to schedule an update for + // the commit side-effects on the root. + markUpdate(workInProgress); + } else if (!fiberRoot.hydrate) { + // Schedule an effect to clear this container at the start of the next commit. + // This handles the case of React rendering into a container with previous children. + // It's also safe to do for updates too, because current.child would only be null + // if the previous render was null (so the the container would already be empty). + workInProgress.flags |= Snapshot; + } + } - { - // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - } - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; -function markRef(current, workInProgress) { - var ref = workInProgress.ref; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } -} + if (current.ref !== workInProgress.ref) { + markRef(workInProgress); + } + } else { + if (!newProps) { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. -function updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - { - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + bubbleProperties(workInProgress); + return null; + } - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); - } - } - } + var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context + // "stack" as the parent. Then append children as we go in beginWork + // or completeWork depending on whether we want to add them top->down or + // bottom->up. Top->down is faster in IE11. - var context; + var _wasHydrated = popHydrationState(); - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + if (_wasHydrated) { + // TODO: Move this and createInstance step into the beginPhase + // to consolidate. + if (prepareToHydrateHostInstance()) { + // If changes to the hydrated node need to be applied at the + // commit-phase we mark this as such. + markUpdate(workInProgress); + } + } else { + var instance = createInstance( + type, + newProps, + rootContainerInstance, + currentHostContext, + workInProgress + ); + appendAllChildren(instance, workInProgress, false, false); + workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. + // (eg DOM renderer supports auto-focus for certain elements). + // Make sure such renderers get scheduled for later work. - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef(workInProgress); + } + } - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + bubbleProperties(workInProgress); + return null; + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); - } finally { - reenableLogs(); + case HostText: { + var newText = newProps; + + if (current && workInProgress.stateNode != null) { + var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need + // to schedule a side-effect to do the updates. + + updateHostText(current, workInProgress, oldText, newText); + } else { + if (typeof newText !== "string") { + if (!(workInProgress.stateNode !== null)) { + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + } // This can happen when we abort work. + } + + var _rootContainerInstance = getRootHostContainer(); + + var _currentHostContext = getHostContext(); + + var _wasHydrated2 = popHydrationState(); + + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } } + + bubbleProperties(workInProgress); + return null; } - setIsRendering(false); - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. -function updateClassComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - { - // This is used by DevTools to force a boundary to error. - switch (shouldError(workInProgress)) { - case false: { - var _instance = workInProgress.stateNode; - var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. - // Is there a better way to do this? + return workInProgress; + } - var tempInstance = new ctor( - workInProgress.memoizedProps, - _instance.context - ); - var state = tempInstance.state; + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - _instance.updater.enqueueSetState(_instance, state, null); + if (current === null); + else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } // If the suspended state of the boundary changes, we need to schedule + // an effect to toggle the subtree's visibility. When we switch from + // fallback -> primary, the inner Offscreen fiber schedules this effect + // as part of its normal complete phase. But when we switch from + // primary -> fallback, the inner Offscreen fiber does not have a complete + // phase. So we need to schedule its effect here. + // + // We also use this flag to connect/disconnect the effects, but the same + // logic applies: when re-connecting, the Offscreen fiber's complete + // phase will handle scheduling the effect. It's only when the fallback + // is active that we have to do anything special. - break; + if (nextDidTimeout && !prevDidTimeout) { + var offscreenFiber = workInProgress.child; + offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything + // in the concurrent tree already suspended during this render. + // This is a known bug. + + if ((workInProgress.mode & ConcurrentMode) !== NoMode) { + // TODO: Move this back to throwException because this is too late + // if this is a large tree which is common for initial loads. We + // don't know if we should restart a render or not until we get + // this marker, and this is too late. + // If this render already had a ping or lower pri updates, + // and this is the first time we know we're going to suspend we + // should be able to immediately restart from within throwException. + var hasInvisibleChildContext = + current === null && + workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + + if ( + hasInvisibleChildContext || + hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ) + ) { + // If this was in an invisible tree or a new render, then showing + // this boundary is ok. + renderDidSuspend(); + } else { + // Otherwise, we're going to have to hide content so we should + // suspend for longer if possible. + renderDidSuspendDelayIfPossible(); + } + } } - case true: { - workInProgress.flags |= DidCapture; - workInProgress.flags |= ShouldCapture; - var error$1 = new Error("Simulated error coming from DevTools"); - var lane = pickArbitraryLane(renderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state + var wakeables = workInProgress.updateQueue; - var update = createClassErrorUpdate( - workInProgress, - createCapturedValue(error$1, workInProgress), - lane - ); - enqueueCapturedUpdate(workInProgress, update); - break; + if (wakeables !== null) { + // Schedule an effect to attach a retry listener to the promise. + // TODO: Move to passive phase + workInProgress.flags |= Update; } - } - if (workInProgress.type !== workInProgress.elementType) { - // Lazy component props can't be validated in createElement - // because they're only guaranteed to be resolved here. - var innerPropTypes = Component.propTypes; + bubbleProperties(workInProgress); - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentNameFromType(Component) - ); + { + if ((workInProgress.mode & ProfileMode) !== NoMode) { + if (nextDidTimeout) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var _primaryChildFragment2 = workInProgress.child; + + if (_primaryChildFragment2 !== null) { + // $FlowFixMe Flow doesn't support type casting in combination with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } } + + return null; } - } // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. - var hasContext; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + bubbleProperties(workInProgress); + return null; - if (instance === null) { - if (current !== null) { - // A class component without an instance only mounts if it suspended - // inside a non-concurrent tree, in an inconsistent state. We want to - // treat it like a new mount, even though an empty version of it already - // committed. Disconnect the alternate pointers. - current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. - - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - shouldUpdate = true; - } else if (current === null) { - // In a resume, we'll already have an instance we can reuse. - shouldUpdate = resumeMountClassInstance( - workInProgress, - Component, - nextProps, - renderLanes - ); - } else { - shouldUpdate = updateClassInstance( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); - } - - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; - { - var inst = workInProgress.stateNode; + case IncompleteClassComponent: { + // Same as class component case. I put it down here so that the tags are + // sequential to ensure this switch is compiled to a jump table. + var _Component = workInProgress.type; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { - error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentNameFromFiber(workInProgress) || "a component" - ); + if (isContextProvider(_Component)) { + popContext(workInProgress); } - didWarnAboutReassigningProps = true; + bubbleProperties(workInProgress); + return null; } - } - return nextUnitOfWork; -} - -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes -) { - // Refs should update even if shouldComponentUpdate returns false - markRef(current, workInProgress); - var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - var instance = workInProgress.stateNode; // Rerender + if (renderedTail === null) { + // We just rendered the head. + if (!didSuspendAlready) { + // This is the first pass. We need to figure out if anything is still + // suspended in the rendered set. + // If new content unsuspended, but there's still some content that + // didn't. Then we need to do a second pass that forces everything + // to keep showing their fallbacks. + // We might be suspended if something in this render pass suspended, or + // something in the previous committed pass suspended. Otherwise, + // there's no chance so we can skip the expensive call to + // findFirstSuspended. + var cannotBeSuspended = + renderHasNotSuspendedYet() && + (current === null || (current.flags & DidCapture) === NoFlags); - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + if (!cannotBeSuspended) { + var row = workInProgress.child; - if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" - ) { - // If we captured an error, but getDerivedStateFromError is not defined, - // unmount all the children. componentDidCatch will schedule an update to - // re-render a fallback. This is temporary until we migrate everyone to - // the new API. - // TODO: Warn in a future release. - nextChildren = null; + while (row !== null) { + var suspended = findFirstSuspended(row); - { - stopProfilerTimerIfRunning(); - } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); + if (suspended !== null) { + didSuspendAlready = true; + workInProgress.flags |= DidCapture; + cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as + // part of the second pass. In that case nothing will subscribe to + // its thennables. Instead, we'll transfer its thennables to the + // SuspenseList so that it can retry if they resolve. + // There might be multiple of these in the list but since we're + // going to wait for all of them anyway, it doesn't really matter + // which ones gets to ping. In theory we could get clever and keep + // track of how many dependencies remain but it gets tricky because + // in the meantime, we can add/remove/change items and dependencies. + // We might bail out of the loop before finding any but that + // doesn't matter since that means that the other boundaries that + // we did find already has their listeners attached. - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + var newThennables = suspended.updateQueue; - try { - instance.render(); - } finally { - reenableLogs(); - } - } + if (newThennables !== null) { + workInProgress.updateQueue = newThennables; + workInProgress.flags |= Update; + } // Rerender the whole list, but this time, we'll force fallbacks + // to stay in place. + // Reset the effect flags before doing the second pass since that's now invalid. + // Reset the child fibers to their original state. - setIsRendering(false); - } - } // React DevTools reads this flag. + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - workInProgress.flags |= PerformedWork; + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - if (current !== null && didCaptureError) { - // If we're recovering from an error, reconcile without reusing any of - // the existing children. Conceptually, the normal children and the children - // that are shown on error are two different sets, so we shouldn't reuse - // normal children even if their identities match. - forceUnmountCurrentAndReconcile( - current, - workInProgress, - nextChildren, - renderLanes - ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } // Memoize state using the values we just used to render. - // TODO: Restructure so we never read values from the instance. + return workInProgress.child; + } - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + row = row.sibling; + } + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); - } + if (renderState.tail !== null && now() > getRenderTargetTime()) { + // We have already passed our CPU deadline but we still have rows + // left in the tail. We'll just give up further attempts to render + // the main content and only render fallbacks. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. - return workInProgress.child; -} + workInProgress.lanes = SomeRetryLane; + } + } else { + cutOffTailIfNeeded(renderState, false); + } // Next we're going to render the tail. + } else { + // Append the rendered row to the child list. + if (!didSuspendAlready) { + var _suspended = findFirstSuspended(renderedTail); -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; + if (_suspended !== null) { + workInProgress.flags |= DidCapture; + didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't + // get lost if this row ends up dropped during a second pass. - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, false); - } + var _newThennables = _suspended.updateQueue; - pushHostContainer(workInProgress, root.containerInfo); -} + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + cutOffTailIfNeeded(renderState, true); // This might have been modified. - if (!(current !== null && updateQueue !== null)) { - throw Error( - "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState.element; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; - var root = workInProgress.stateNode; - // being called "element". - - var nextChildren = nextState.element; - - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } - - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; - - while (node) { - // Mark each child as hydrating. This is a fast path to know whether this - // tree is part of a hydrating tree. This is used to determine if a child - // node has fully mounted yet, and for scheduling event replaying. - // Conceptually this is similar to Placement in that a new subtree is - // inserted into the React tree here. It just happens to not need DOM - // mutations because it already exists. - node.flags = (node.flags & ~Placement) | Hydrating; - node = node.sibling; - } - } else { - // Otherwise reset hydration state in case we aborted and resumed another - // root. - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } - - return workInProgress.child; -} - -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); - - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We're done. + bubbleProperties(workInProgress); + return null; + } + } else if ( + // The time it took to render last row is greater than the remaining + // time we have to render. So rendering one more row would likely + // exceed it. + now() * 2 - renderState.renderingStartTime > + getRenderTargetTime() && + renderLanes !== OffscreenLane + ) { + // We have now passed our CPU deadline and we'll just give up further + // attempts to render the main content and only render fallbacks. + // The assumption is that this is usually faster. + workInProgress.flags |= DidCapture; + didSuspendAlready = true; + cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this + // to get it started back up to attempt the next item. While in terms + // of priority this work has the same priority as this current render, + // it's not part of the same transition once the transition has + // committed. If it's sync, we still want to yield so that it can be + // painted. Conceptually, this is really the same as pinging. + // We can use any RetryLane even if it's the one currently rendering + // since we're leaving it behind on this node. - if (prevProps !== null && shouldSetTextContent()) { - // If we're switching from a direct text child to a normal child, or to - // empty, we need to schedule the text content to be reset. - workInProgress.flags |= ContentReset; - } + workInProgress.lanes = SomeRetryLane; + } + } - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (renderState.isBackwards) { + // The effect list of the backwards tail will have been added + // to the end. This breaks the guarantee that life-cycles fire in + // sibling order but that isn't a strong guarantee promised by React. + // Especially since these might also just pop in during future commits. + // Append to the beginning of the list. + renderedTail.sibling = workInProgress.child; + workInProgress.child = renderedTail; + } else { + var previousSibling = renderState.last; -function updateHostText(current, workInProgress) { - // immediately after. + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - return null; -} + renderState.last = renderedTail; + } + } -function mountLazyComponent( - _current, - workInProgress, - elementType, - updateLanes, - renderLanes -) { - if (_current !== null) { - // A lazy component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + if (renderState.tail !== null) { + // We still have tail rows to render. + // Pop a row. + var next = renderState.tail; + renderState.rendering = next; + renderState.tail = next.sibling; + renderState.renderingStartTime = now(); + next.sibling = null; // Restore the context. + // TODO: We can probably just avoid popping it instead and only + // setting it the first time we go from not suspended to suspended. - workInProgress.flags |= Placement; - } + var suspenseContext = suspenseStackCursor.current; - var props = workInProgress.pendingProps; - var lazyComponent = elementType; - var payload = lazyComponent._payload; - var init = lazyComponent._init; - var Component = init(payload); // Store the unwrapped component in the type. + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); + return next; } - child = updateFunctionComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; + bubbleProperties(workInProgress); + return null; } - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; + case ScopeComponent: { + break; } - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); - } + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; - } + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" && // LegacyHidden doesn't do any hiding — it only pre-renders. + workInProgress.tag !== LegacyHiddenComponent + ) { + workInProgress.flags |= Visibility; + } + } - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentNameFromType(Component) - ); + if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { + bubbleProperties(workInProgress); + } else { + // Don't bubble properties for hidden children unless we're rendering + // at offscreen priority. + if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { + bubbleProperties(workInProgress); + + { + // Check if there was an insertion or update in the hidden subtree. + // If so, we need to hide those nodes in the commit phase, so + // schedule a visibility effect. + if ( + workInProgress.tag !== LegacyHiddenComponent && + workInProgress.subtreeFlags & (Placement | Update) && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Visibility; + } } } } - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; + return null; } } - var hint = ""; - - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; - } - } // This message intentionally doesn't mention ForwardRef or MemoComponent - // because the fact that it's a separate type of work is an - // implementation detail. - { throw Error( - "Element type is invalid. Received a promise that resolves to: " + - Component + - ". Lazy element type must resolve to a class or function." + - hint + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." ); } } -function mountIncompleteClassComponent( - _current, +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; + +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} + +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + if (current === null) { + // If this is a fresh new component that hasn't been rendered yet, we + // won't update its child set by applying minimal side-effects. Instead, + // we will add them all to the child before it gets rendered. That means + // we can optimize this reconciliation pass by not tracking side-effects. + workInProgress.child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + // If the current child is the same as the work in progress, it means that + // we haven't yet started any work on these children. Therefore, we use + // the clone algorithm to create a copy of all the current children. + // If we had any progressed work already, that is invalid at this point so + // let's throw it out. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); + } +} + +function forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes +) { + // This function is fork of reconcileChildren. It's used in cases where we + // want to reconcile without matching against the existing set. This has the + // effect of all current children being unmounted; even if the type and key + // are the same, the old child is unmounted and a new child is created. + // + // To do this, we're going to go through the reconcile algorithm twice. In + // the first pass, we schedule a deletion for all the current children by + // passing null. + workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes + ); // In the second pass, we mount the new children. The trick here is that we + // pass null in place of where we usually pass the current child set. This has + // the effect of remounting all children regardless of whether their + // identities match. + + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); +} + +function updateForwardRef( + current, workInProgress, Component, nextProps, renderLanes ) { - if (_current !== null) { - // An incomplete component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens after the first render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) + ); + } + } + } - workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - var hasContext; + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); } - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function mountIndeterminateComponent( - _current, +function updateMemoComponent( + current, workInProgress, Component, + nextProps, renderLanes ) { - if (_current !== null) { - // An indeterminate component only mounts if it suspended inside a non- - // concurrent tree, in an inconsistent state. We want to treat it like - // a new mount, even though an empty version of it already committed. - // Disconnect the alternate pointers. - _current.alternate = null; - workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - - workInProgress.flags |= Placement; - } - - var props = workInProgress.pendingProps; - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } - - prepareToReadContext(workInProgress, renderLanes); - var value; + if (current === null) { + var type = Component.type; - { if ( - Component.prototype && - typeof Component.prototype.render === "function" + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined ) { - var componentName = getComponentNameFromType(Component) || "Unknown"; + var resolvedType = type; - if (!didWarnAboutBadClass[componentName]) { - error( - "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + - "This is likely to cause errors. Change %s to extend React.Component instead.", - componentName, - componentName - ); + { + resolvedType = resolveFunctionForHotReloading(type); + } // If this is a plain function component without default props, + // and with only the default shallow comparison, we upgrade it + // to a SimpleMemoComponent to allow fast path updates. - didWarnAboutBadClass[componentName] = true; + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + renderLanes + ); } - if (workInProgress.mode & StrictLegacyMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + { + var innerPropTypes = type.propTypes; + + if (innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(type) + ); + } } - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( + var child = createFiberFromTypeAndProps( + Component.type, null, + nextProps, workInProgress, - Component, - props, - context, + workInProgress.mode, renderLanes ); - setIsRendering(false); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } { - // Support for module components is deprecated and is removed behind a flag. - // Whether or not it would crash later, we want to show a good message in DEV first. - if ( - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - var _componentName = getComponentNameFromType(Component) || "Unknown"; - - if (!didWarnAboutModulePatternComponent[_componentName]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName, - _componentName, - _componentName - ); + var _type = Component.type; + var _innerPropTypes = _type.propTypes; - didWarnAboutModulePatternComponent[_componentName] = true; - } + if (_innerPropTypes) { + // Inner memo component props aren't currently validated in createElement. + // We could move it there, but we'd still need this for lazy code path. + checkPropTypes( + _innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(_type) + ); } } - if ( - // Run these checks in production only if the flag is off. - // Eventually we'll delete this branch altogether. - typeof value === "object" && - value !== null && - typeof value.render === "function" && - value.$$typeof === undefined - ) { - { - var _componentName2 = getComponentNameFromType(Component) || "Unknown"; - - if (!didWarnAboutModulePatternComponent[_componentName2]) { - error( - "The <%s /> component appears to be a function component that returns a class instance. " + - "Change %s to a class that extends React.Component instead. " + - "If you can't use a class try assigning the prototype on the function as a workaround. " + - "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + - "cannot be called with `new` by React.", - _componentName2, - _componentName2, - _componentName2 - ); - - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance + var currentChild = current.child; // This is always exactly one child - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); - workInProgress.memoizedState = null; - workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. - // During mounting we don't know the child context yet as the instance doesn't exist. - // We will invalidate the child context in finishClassComponent() right after rendering. + if (!hasScheduledUpdateOrContext) { + // This will be the props with resolved defaultProps, + // unlike current.memoizedProps which will be the unresolved ones. + var prevProps = currentChild.memoizedProps; // Default to shallow comparison - var hasContext = false; + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } + } // React DevTools reads this flag. - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + // TODO: current can be non-null here even if the component + // hasn't yet mounted. This happens when the inner render suspends. + // We'll need to figure out if this is fine or can cause issues. + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var outerMemoType = workInProgress.elementType; + + if (outerMemoType.$$typeof === REACT_LAZY_TYPE) { + // We warn when you define propTypes on lazy() + // so let's just skip over it to find memo() outer wrapper. + // Inner props for memo are validated later. + var lazyComponent = outerMemoType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. + + var outerPropTypes = outerMemoType && outerMemoType.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentNameFromType(outerMemoType) ); - } finally { - reenableLogs(); } } } + } - reconcileChildren(null, workInProgress, value, renderLanes); - - { - validateFunctionComponentInDev(workInProgress, Component); - } + if (current !== null) { + var prevProps = current.memoizedProps; - return workInProgress.child; - } -} + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; -function validateFunctionComponentInDev(workInProgress, Component) { - { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" + if (!checkScheduledUpdateOrContext(current, renderLanes)) { + // The pending lanes were cleared at the beginning of beginWork. We're + // about to bail out, but there might be other lanes that weren't + // included in the current render. Usually, the priority level of the + // remaining updates is accumulated during the evaluation of the + // component (i.e. when processing the update queue). But since since + // we're bailing out early *without* evaluating the component, we need + // to account for it here, too. Reset to the value of the current fiber. + // NOTE: This only applies to SimpleMemoComponent, not MemoComponent, + // because a MemoComponent fiber does not have hooks or an update queue; + // rather, it wraps around an inner component, which may or may not + // contains hooks. + // TODO: Move the reset at in beginWork out of the common path so that + // this is no longer necessary. + workInProgress.lanes = current.lanes; + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); + } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; } } + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; // If this is not null, this is a cache pool that was carried over from the + // previous render. We will push this to the cache pool context so that we can + // resume in-flight requests. - var warningKey = ownerName || ""; - var debugSource = workInProgress._debugSource; + var spawnedCachePool = null; - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + // Rendering a hidden tree. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + var nextState = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + // We're hidden, and we're not rendering at Offscreen. We will bail out + // and resume this tree later. + var nextBaseLanes; - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + if (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } - } + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes, + cachePool: spawnedCachePool + }; + workInProgress.memoizedState = _nextState; + workInProgress.updateQueue = null; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentNameFromType(Component) || "Unknown"; + pushRenderLanes(workInProgress, nextBaseLanes); - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); + return null; + } else { + var _nextState2 = { + baseLanes: NoLanes, + cachePool: null + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentNameFromType(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 - ); + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; - } + workInProgress.memoizedState = null; + } else { + // We weren't previously hidden, and we still aren't, so there's nothing + // special to do. Need to push to the stack regardless, though, to avoid + // a push/pop misalignment. + _subtreeRenderLanes = renderLanes; } - } -} -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; + pushRenderLanes(workInProgress, _subtreeRenderLanes); + } -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes, - cachePool: getSuspendedCachePool() - }; + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // TODO: Optimize this to use the OffscreenComponent fiber instead of + // an extra HostComponent fiber. Need to make sure this doesn't break Fabric + // or some other infra that expects a HostComponent. + var isHidden = + nextProps.mode === "hidden" && + workInProgress.tag !== LegacyHiddenComponent; + var offscreenContainer = reconcileOffscreenHostContainer( + current, + workInProgress + ); + return offscreenContainer; + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; + } } -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - var cachePool = null; - - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), - cachePool: cachePool - }; -} // TODO: Probably should inline this back - -function shouldRemainOnFallback( - suspenseContext, - current, - workInProgress, +function reconcileOffscreenHostContainer( + currentOffscreen, + offscreen, + isHidden, + children, renderLanes ) { - // If we're already showing a fallback, there are cases where we need to - // remain on that fallback regardless of whether the content has resolved. - // For example, SuspenseList coordinates when nested content appears. - if (current !== null) { - var suspenseState = current.memoizedState; + var containerProps = getOffscreenContainerProps(); + var hostContainer; - if (suspenseState === null) { - // Currently showing content. Don't hide it, even if ForceSuspenseFallack - // is true. More precise name might be "ForceRemainSuspenseFallback". - // Note: This is a factoring smell. Can't remain on a fallback if there's - // no fallback to remain on. - return false; + if (currentOffscreen === null) { + hostContainer = createOffscreenHostContainerFiber( + containerProps, + offscreen.mode + ); + } else { + var currentHostContainer = currentOffscreen.child; + + if (currentHostContainer === null) { + hostContainer = createOffscreenHostContainerFiber( + containerProps, + offscreen.mode + ); + hostContainer.flags |= Placement; + } else { + hostContainer = createWorkInProgress( + currentHostContainer, + containerProps + ); } - } // Not currently showing content. Consult the Suspense context. + } - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + hostContainer.return = offscreen; + offscreen.child = hostContainer; + return hostContainer; +} // Note: These happen to have identical begin phases, for now. We shouldn't hold +// ourselves to this constraint, though. If the behavior diverges, we should +// fork the function. + +var updateLegacyHiddenComponent = updateOffscreenComponent; + +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} + +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); +function updateProfiler(current, workInProgress, renderLanes) { + { + workInProgress.flags |= Update; + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } + } + + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. +function markRef$1(current, workInProgress) { + var ref = workInProgress.ref; - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; - } + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; } +} - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; +function updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + { + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; - if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { - // Something in this boundary's subtree already suspended. Switch to - // rendering the fallback children. - showFallback = true; - workInProgress.flags &= ~DidCapture; - } else { - // Attempting the main content - if (current === null || current.memoizedState !== null) { - // This is a new mount or this boundary is already showing a fallback state. - // Mark this subtree context as having at least one invisible parent that could - // handle the fallback state. - // Avoided boundaries are not considered since they cannot handle preferred fallback states. - if (nextProps.unstable_avoidThisFallback !== true) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) ); } } } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense - // boundary's children. This involves some custom reconcilation logic. Two - // main reasons this is so complicated. - // - // First, Legacy Mode has different semantics for backwards compatibility. The - // primary tree will commit in an inconsistent state, so when we do the - // second pass to render the fallback, we do some exceedingly, uh, clever - // hacks to make that not totally break. Like transferring effects and - // deletions from hidden tree. In Concurrent Mode, it's much simpler, - // because we bailout on the primary tree completely and leave it in its old - // state, no effects. Same as what we do for Offscreen (except that - // Offscreen doesn't have the first render pass). - // - // Second is hydration. During hydration, the Suspense fiber has a slightly - // different layout, where the child points to a dehydrated fragment, which - // contains the DOM rendered by the server. - // - // Third, even if you set all that aside, Suspense is like error boundaries in - // that we first we try to render one tree, and if that fails, we render again - // and switch to a different tree. Like a try/catch block. So we have to track - // which branch we're currently rendering. Ideally we would model this using - // a stack. - - if (current === null) { - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; + var context; - if (showFallback) { - var fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - var primaryChildFragment = workInProgress.child; - primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return fallbackFragment; - } else if (typeof nextProps.unstable_expectedLoadTime === "number") { - // This is a CPU-bound tree. Skip this tree and show a placeholder to - // unblock the surrounding content. Then immediately retry after the - // initial commit. - var _fallbackFragment = mountSuspenseFallbackChildren( - workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to - // get it started back up to attempt the next item. While in terms of - // priority this work has the same priority as this current render, it's - // not part of the same transition once the transition has committed. If - // it's sync, we still want to yield so that it can be painted. - // Conceptually, this is really the same as pinging. We can use any - // RetryLane even if it's the one currently rendering since we're leaving - // it behind on this node. + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); - workInProgress.lanes = SomeRetryLane; - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); - } - } else { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - var _fallbackChildFragment = updateSuspenseFallbackChildren( + try { + nextChildren = renderWithHooks( current, workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, + Component, + nextProps, + context, renderLanes ); + } finally { + reenableLogs(); + } + } - var _primaryChildFragment3 = workInProgress.child; - var prevOffscreenState = current.child.memoizedState; - _primaryChildFragment3.memoizedState = - prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); - _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment; - } else { - var _nextPrimaryChildren3 = nextProps.children; + setIsRendering(false); + } - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); + if (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. - workInProgress.memoizedState = null; - return _primaryChildFragment4; - } - } else { - // The current tree is not already showing a fallback. - if (showFallback) { - // Timed out. - var _nextFallbackChildren3 = nextProps.fallback; - var _nextPrimaryChildren4 = nextProps.children; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes +function updateClassComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + { + // This is used by DevTools to force a boundary to error. + switch (shouldError(workInProgress)) { + case false: { + var _instance = workInProgress.stateNode; + var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack. + // Is there a better way to do this? + + var tempInstance = new ctor( + workInProgress.memoizedProps, + _instance.context ); + var state = tempInstance.state; - var _primaryChildFragment5 = workInProgress.child; - var _prevOffscreenState = current.child.memoizedState; - _primaryChildFragment5.memoizedState = - _prevOffscreenState === null - ? mountSuspenseOffscreenState(renderLanes) - : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); - _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( - current, - renderLanes - ); // Skip the primary children, and continue working on the - // fallback children. + _instance.updater.enqueueSetState(_instance, state, null); - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; + break; + } + + case true: { + workInProgress.flags |= DidCapture; + workInProgress.flags |= ShouldCapture; + var error$1 = new Error("Simulated error coming from DevTools"); + var lane = pickArbitraryLane(renderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, + var update = createClassErrorUpdate( workInProgress, - _nextPrimaryChildren5, - renderLanes + createCapturedValue(error$1, workInProgress), + lane ); + enqueueCapturedUpdate(workInProgress, update); + break; + } + } - workInProgress.memoizedState = null; - return _primaryChildFragment6; + if (workInProgress.type !== workInProgress.elementType) { + // Lazy component props can't be validated in createElement + // because they're only guaranteed to be resolved here. + var innerPropTypes = Component.propTypes; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentNameFromType(Component) + ); } } - } -} + } // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. -function mountSuspensePrimaryChildren( - workInProgress, - primaryChildren, - renderLanes -) { - var mode = workInProgress.mode; - var primaryChildProps = { - mode: "visible", - children: primaryChildren - }; - var primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - renderLanes, - null - ); - primaryChildFragment.return = workInProgress; - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} + var hasContext; -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - if ( - (mode & ConcurrentMode) === NoMode && - progressedPrimaryFragment !== null - ) { - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = 0; - primaryChildFragment.treeBaseDuration = 0; - } + if (instance === null) { + if (current !== null) { + // A class component without an instance only mounts if it suspended + // inside a non-concurrent tree, in an inconsistent state. We want to + // treat it like a new mount, even though an empty version of it already + // committed. Disconnect the alternate pointers. + current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. + + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + shouldUpdate = true; + } else if (current === null) { + // In a resume, we'll already have an instance we can reuse. + shouldUpdate = resumeMountClassInstance( + workInProgress, + Component, + nextProps, + renderLanes ); } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes ); } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} - -function createWorkInProgressOffscreenFiber(current, offscreenProps) { - // The props argument to `createWorkInProgress` is `any` typed, so we use this - // wrapper function to constrain it. - return createWorkInProgress(current, offscreenProps); -} - -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren - } + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes ); - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; - } - - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + { + var inst = workInProgress.stateNode; - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - var deletions = workInProgress.deletions; + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { + error( + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentNameFromFiber(workInProgress) || "a component" + ); + } - if (deletions === null) { - workInProgress.deletions = [currentFallbackChildFragment]; - workInProgress.flags |= ChildDeletion; - } else { - deletions.push(currentFallbackChildFragment); + didWarnAboutReassigningProps = true; } } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; + return nextUnitOfWork; } -function updateSuspenseFallbackChildren( +function finishClassComponent( current, workInProgress, - primaryChildren, - fallbackChildren, + Component, + shouldUpdate, + hasContext, renderLanes ) { - var mode = workInProgress.mode; - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; + // Refs should update even if shouldComponentUpdate returns false + markRef$1(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was - // already cloned. In legacy mode, the only case where this isn't true is - // when DevTools forces us to display a fallback; we skip the first render - // pass entirely and go straight to rendering the fallback. (In Concurrent - // Mode, SuspenseList can also trigger this scenario, but this is a legacy- - // only codepath.) - workInProgress.child !== currentPrimaryChildFragment - ) { - var progressedPrimaryFragment = workInProgress.child; - primaryChildFragment = progressedPrimaryFragment; - primaryChildFragment.childLanes = NoLanes; - primaryChildFragment.pendingProps = primaryChildProps; + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); + } - if (workInProgress.mode & ProfileMode) { - // Reset the durations from the first pass so they aren't included in the - // final amounts. This seems counterintuitive, since we're intentionally - // not measuring part of the render phase, but this makes it match what we - // do in Concurrent Mode. - primaryChildFragment.actualDuration = 0; - primaryChildFragment.actualStartTime = -1; - primaryChildFragment.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration; - primaryChildFragment.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration; - } // The fallback fiber was added as a deletion during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; + + if ( + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" + ) { + // If we captured an error, but getDerivedStateFromError is not defined, + // unmount all the children. componentDidCatch will schedule an update to + // re-render a fallback. This is temporary until we migrate everyone to + // the new API. + // TODO: Warn in a future release. + nextChildren = null; - workInProgress.deletions = null; + { + stopProfilerTimerIfRunning(); + } } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); // Since we're reusing a current tree, we need to reuse the flags, too. - // (We don't do this in legacy mode, because in legacy mode we don't re-use - // the current tree; see previous branch.) + { + setIsRendering(true); + nextChildren = instance.render(); - primaryChildFragment.subtreeFlags = - currentPrimaryChildFragment.subtreeFlags & StaticMask; - } + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - var fallbackChildFragment; + try { + instance.render(); + } finally { + reenableLogs(); + } + } - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren + setIsRendering(false); + } + } // React DevTools reads this flag. + + workInProgress.flags |= PerformedWork; + + if (current !== null && didCaptureError) { + // If we're recovering from an error, reconcile without reusing any of + // the existing children. Conceptually, the normal children and the children + // that are shown on error are two different sets, so we shouldn't reuse + // normal children even if their identities match. + forceUnmountCurrentAndReconcile( + current, + workInProgress, + nextChildren, + renderLanes ); } else { - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); // Needs a placement effect because the parent (the Suspense boundary) already - // mounted but this is a new fiber. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } // Memoize state using the values we just used to render. + // TODO: Restructure so we never read values from the instance. - fallbackChildFragment.flags |= Placement; + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; + return workInProgress.child; } -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); } - scheduleWorkOnParentPath(fiber.return, renderLanes); + pushHostContainer(workInProgress, root.containerInfo); } -function propagateSuspenseContextChange( - workInProgress, - firstChild, - renderLanes -) { - // Mark any Suspense boundaries with fallbacks as having work to do. - // If they were previously forced into fallbacks, they may now be able - // to unblock. - var node = firstChild; +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + if (!(current !== null && updateQueue !== null)) { + throw Error( + "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." + ); + } - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); - } - } else if (node.tag === SuspenseListComponent) { - // If the tail is hidden there might not be an Suspense boundaries - // to schedule work on. In this case we have to schedule it on the - // list itself. - // We don't have to traverse to the children of the list since - // the list will propagate the change when it rerenders. - scheduleWorkOnFiber(node, renderLanes); - } else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState.element; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; + var root = workInProgress.stateNode; + // being called "element". - if (node === workInProgress) { - return; - } + var nextChildren = nextState.element; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - node = node.return; - } + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; - node.sibling.return = node.return; - node = node.sibling; + while (node) { + // Mark each child as hydrating. This is a fast path to know whether this + // tree is part of a hydrating tree. This is used to determine if a child + // node has fully mounted yet, and for scheduling event replaying. + // Conceptually this is similar to Placement in that a new subtree is + // inserted into the React tree here. It just happens to not need DOM + // mutations because it already exists. + node.flags = (node.flags & ~Placement) | Hydrating; + node = node.sibling; + } + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); } -} -function findLastContentRow(firstChild) { - // This is going to find the last row among these children that is already - // showing content on the screen, as opposed to being in fallback state or - // new. If a row has multiple Suspense boundaries, any of them being in the - // fallback state, counts as the whole row being in a fallback state. - // Note that the "rows" will be workInProgress, but any nested children - // will still be current since we haven't rendered them yet. The mounted - // order may not be the same as the new order. We use the new order. - var row = firstChild; - var lastContentRow = null; + return workInProgress.child; +} - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. +function updateHostComponent$1(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + var type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - row = row.sibling; + if (prevProps !== null && shouldSetTextContent()) { + // If we're switching from a direct text child to a normal child, or to + // empty, we need to schedule the text content to be reset. + workInProgress.flags |= ContentReset; } - return lastContentRow; + markRef$1(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; +function updateHostText$1(current, workInProgress) { + // immediately after. - if (typeof revealOrder === "string") { - switch (revealOrder.toLowerCase()) { - case "together": - case "forwards": - case "backwards": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'Use lowercase "%s" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + return null; +} - break; - } +function mountLazyComponent( + _current, + workInProgress, + elementType, + renderLanes +) { + if (_current !== null) { + // A lazy component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - case "forward": - case "backward": { - error( - '"%s" is not a valid value for revealOrder on . ' + - 'React uses the -s suffix in the spelling. Use "%ss" instead.', - revealOrder, - revealOrder.toLowerCase() - ); + workInProgress.flags |= Placement; + } - break; - } + var props = workInProgress.pendingProps; + var lazyComponent = elementType; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + var Component = init(payload); // Store the unwrapped component in the type. - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - break; - } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component ); } - } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; + } - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - } -} -function validateSuspenseListNestedChild(childSlot, index) { - { - var isAnArray = isArray(childSlot); - var isIterable = - !isAnArray && typeof getIteratorFn(childSlot) === "function"; + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; - if (isAnArray || isIterable) { - var type = isAnArray ? "array" : "iterable"; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentNameFromType(Component) + ); + } + } + } - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + renderLanes ); - - return false; + return child; } } - return true; -} + var hint = ""; -function validateSuspenseListChildren(children, revealOrder) { { if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false + Component !== null && + typeof Component === "object" && + Component.$$typeof === REACT_LAZY_TYPE ) { - if (isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; - } - } - } else { - var iteratorFn = getIteratorFn(children); - - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); - - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; - - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } - - _i++; - } - } - } else { - error( - 'A single row was passed to a . ' + - "This is not useful since it needs multiple rows. " + - "Did you mean to pass multiple children or an array?", - revealOrder - ); - } - } + hint = " Did you wrap a component in React.lazy() more than once?"; } + } // This message intentionally doesn't mention ForwardRef or MemoComponent + // because the fact that it's a separate type of work is an + // implementation detail. + + { + throw Error( + "Element type is invalid. Received a promise that resolves to: " + + Component + + ". Lazy element type must resolve to a class or function." + + hint + ); } } -function initSuspenseListRenderState( +function mountIncompleteClassComponent( + _current, workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode + Component, + nextProps, + renderLanes ) { - var renderState = workInProgress.memoizedState; - - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }; - } else { - // We can reuse the existing object from previous renders. - renderState.isBackwards = isBackwards; - renderState.rendering = null; - renderState.renderingStartTime = 0; - renderState.last = lastContentRow; - renderState.tail = tail; - renderState.tailMode = tailMode; - } -} // This can end up rendering this component multiple passes. -// The first pass splits the children fibers into two sets. A head and tail. -// We first render the head. If anything is in fallback state, we do another -// pass through beginWork to rerender all children (including the tail) with -// the force suspend context. If the first render didn't have anything in -// in fallback state. Then we render each row in the tail one-by-one. -// That happens in the completeWork phase without going back to beginWork. - -function updateSuspenseListComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var revealOrder = nextProps.revealOrder; - var tailMode = nextProps.tail; - var newChildren = nextProps.children; - validateRevealOrder(revealOrder); - validateTailOptions(tailMode, revealOrder); - validateSuspenseListChildren(newChildren, revealOrder); - reconcileChildren(current, workInProgress, newChildren, renderLanes); - var suspenseContext = suspenseStackCursor.current; - var shouldForceFallback = hasSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; - - if (didSuspendBefore) { - // If we previously forced a fallback, we need to schedule work - // on any nested boundaries to let them know to try to render - // again. This is the same as context updating. - propagateSuspenseContextChange( - workInProgress, - workInProgress.child, - renderLanes - ); - } + if (_current !== null) { + // An incomplete component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. - pushSuspenseContext(workInProgress, suspenseContext); + workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` + // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy mode, SuspenseList doesn't work so we just - // use make it a noop by treating it as the default revealOrder. - workInProgress.memoizedState = null; + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; + hasContext = false; + } - if (lastContentRow === null) { - // The whole list is part of the tail. - // TODO: We could fast path by just rendering the tail now. - tail = workInProgress.child; - workInProgress.child = null; - } else { - // Disconnect the tail rows after the content row. - // We're going to render them separately later. - tail = lastContentRow.sibling; - lastContentRow.sibling = null; - } + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode - ); - break; - } +function mountIndeterminateComponent( + _current, + workInProgress, + Component, + renderLanes +) { + if (_current !== null) { + // An indeterminate component only mounts if it suspended inside a non- + // concurrent tree, in an inconsistent state. We want to treat it like + // a new mount, even though an empty version of it already committed. + // Disconnect the alternate pointers. + _current.alternate = null; + workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect - case "backwards": { - // We're going to find the first row that has existing content. - // At the same time we're going to reverse the list of everything - // we pass in the meantime. That's going to be our tail in reverse - // order. - var _tail = null; - var row = workInProgress.child; - workInProgress.child = null; + workInProgress.flags |= Placement; + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + var props = workInProgress.pendingProps; + var context; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + prepareToReadContext(workInProgress, renderLanes); + var value; - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode - ); - break; - } + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentNameFromType(Component) || "Unknown"; - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined + if (!didWarnAboutBadClass[componentName]) { + error( + "The <%s /> component appears to have a render method, but doesn't extend React.Component. " + + "This is likely to cause errors. Change %s to extend React.Component instead.", + componentName, + componentName ); - break; - } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; + didWarnAboutBadClass[componentName] = true; } } - } - - return workInProgress.child; -} -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } - if (current === null) { - // Portals are special because we don't append the children during mount - // but at commit. Therefore we need to track insertions which the normal - // flow doesn't do during mount. This doesn't happen at the root because - // the root always starts with a "current" with a null child. - // TODO: Consider unifying this with how the root works. - workInProgress.child = reconcileChildFibers( - workInProgress, + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( null, - nextChildren, + workInProgress, + Component, + props, + context, renderLanes ); - } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); + setIsRendering(false); } - return workInProgress.child; -} - -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - -function updateContextProvider(current, workInProgress, renderLanes) { - var providerType = workInProgress.type; - var context = providerType._context; - var newProps = workInProgress.pendingProps; - var oldProps = workInProgress.memoizedProps; - var newValue = newProps.value; + workInProgress.flags |= PerformedWork; { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + // Support for module components is deprecated and is removed behind a flag. + // Whether or not it would crash later, we want to show a good message in DEV first. + if ( + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + var _componentName = getComponentNameFromType(Component) || "Unknown"; + if (!didWarnAboutModulePatternComponent[_componentName]) { error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName, + _componentName, + _componentName ); + + didWarnAboutModulePatternComponent[_componentName] = true; } } + } - var providerPropTypes = workInProgress.type.propTypes; + if ( + // Run these checks in production only if the flag is off. + // Eventually we'll delete this branch altogether. + typeof value === "object" && + value !== null && + typeof value.render === "function" && + value.$$typeof === undefined + ) { + { + var _componentName2 = getComponentNameFromType(Component) || "Unknown"; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + if (!didWarnAboutModulePatternComponent[_componentName2]) { + error( + "The <%s /> component appears to be a function component that returns a class instance. " + + "Change %s to a class that extends React.Component instead. " + + "If you can't use a class try assigning the prototype on the function as a workaround. " + + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + + "cannot be called with `new` by React.", + _componentName2, + _componentName2, + _componentName2 + ); + + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance + + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + + workInProgress.memoizedState = null; + workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches. + // During mounting we don't know the child context yet as the instance doesn't exist. + // We will invalidate the child context in finishClassComponent() right after rendering. + + var hasContext = false; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - } - pushProvider(workInProgress, context, newValue); + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); + } else { + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - { - if (oldProps !== null) { - var oldValue = oldProps.value; + { + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); - if (objectIs(oldValue, newValue)) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, + try { + value = renderWithHooks( + null, workInProgress, + Component, + props, + context, renderLanes ); + } finally { + reenableLogs(); } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, renderLanes); } } - } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + reconcileChildren(null, workInProgress, value, renderLanes); -var hasWarnedAboutUsingContextAsConsumer = false; + { + validateFunctionComponentInDev(workInProgress, Component); + } -function updateContextConsumer(current, workInProgress, renderLanes) { - var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In - // DEV mode, we create a separate object for Context.Consumer that acts - // like a proxy to Context. This proxy object adds unnecessary code in PROD - // so we use the old behaviour (Context.Consumer references Context) to - // reduce size and overhead. The separate object references context via - // a property called "_context", which also gives us the ability to check - // in DEV mode if this property exists or not and warn if it does not. + return workInProgress.child; + } +} +function validateFunctionComponentInDev(workInProgress, Component) { { - if (context._context === undefined) { - // This may be because it's a Context (rather than a Consumer). - // Or it may be because it's older React where they're the same thing. - // We only want to warn if we're sure it's a new React. - if (context !== context.Consumer) { - if (!hasWarnedAboutUsingContextAsConsumer) { - hasWarnedAboutUsingContextAsConsumer = true; - - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); } - } else { - context = context._context; } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; - - { - if (typeof render !== "function") { - error( - "A context consumer was rendered with multiple children, or a child " + - "that isn't a function. A context consumer expects a single child " + - "that is a function. If you did pass a function, make sure there " + - "is no trailing or leading whitespace around it." - ); - } - } + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context); - var newChildren; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + var warningKey = ownerName || ""; + var debugSource = workInProgress._debugSource; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); - } + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentNameFromType(Component) || "Unknown"; - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { - // The children don't have any work either. We can skip them. - // TODO: Once we add back resuming, we should check if the children are - // a work-in-progress set. If so, we need to transfer their effects. - { - return null; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } } - } // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - - cloneChildFibers(current, workInProgress); - return workInProgress.child; -} -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentNameFromType(Component) || "Unknown"; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } + } +} - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; +} - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + var cachePool = null; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), + cachePool: cachePool + }; +} // TODO: Probably should inline this back - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } - } +function shouldRemainOnFallback( + suspenseContext, + current, + workInProgress, + renderLanes +) { + // If we're already showing a fallback, there are cases where we need to + // remain on that fallback regardless of whether the content has resolved. + // For example, SuspenseList coordinates when nested content appears. + if (current !== null) { + var suspenseState = current.memoizedState; - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + if (suspenseState === null) { + // Currently showing content. Don't hide it, even if ForceSuspenseFallack + // is true. More precise name might be "ForceRemainSuspenseFallback". + // Note: This is a factoring smell. Can't remain on a fallback if there's + // no fallback to remain on. + return false; + } + } // Not currently showing content. Consult the Suspense context. - var deletions = returnFiber.deletions; + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} - if (deletions === null) { - returnFiber.deletions = [current]; - returnFiber.flags |= ChildDeletion; - } else { - deletions.push(current); - } +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - return newWorkInProgress; + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } } -} -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - { - if (workInProgress._debugNeedsRemount && current !== null) { - // This will restart the begin phase with a new fiber. - return remountFiber( - current, - workInProgress, - createFiberFromTypeAndProps( - workInProgress.type, - workInProgress.key, - workInProgress.pendingProps, - workInProgress._debugOwner || null, - workInProgress.mode, - workInProgress.lanes - ) - ); + if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) { + // Something in this boundary's subtree already suspended. Switch to + // rendering the fallback children. + showFallback = true; + workInProgress.flags &= ~DidCapture; + } else { + // Attempting the main content + if (current === null || current.memoizedState !== null) { + // This is a new mount or this boundary is already showing a fallback state. + // Mark this subtree context as having at least one invisible parent that could + // handle the fallback state. + // Avoided boundaries are not considered since they cannot handle preferred fallback states. + if (nextProps.unstable_avoidThisFallback !== true) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } } } - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense + // boundary's children. This involves some custom reconcilation logic. Two + // main reasons this is so complicated. + // + // First, Legacy Mode has different semantics for backwards compatibility. The + // primary tree will commit in an inconsistent state, so when we do the + // second pass to render the fallback, we do some exceedingly, uh, clever + // hacks to make that not totally break. Like transferring effects and + // deletions from hidden tree. In Concurrent Mode, it's much simpler, + // because we bailout on the primary tree completely and leave it in its old + // state, no effects. Same as what we do for Offscreen (except that + // Offscreen doesn't have the first render pass). + // + // Second is hydration. During hydration, the Suspense fiber has a slightly + // different layout, where the child points to a dehydrated fragment, which + // contains the DOM rendered by the server. + // + // Third, even if you set all that aside, Suspense is like error boundaries in + // that we first we try to render one tree, and if that fails, we render again + // and switch to a different tree. Like a try/catch block. So we have to track + // which branch we're currently rendering. Ideally we would model this using + // a stack. - if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type - ) { - // If props or context changed, mark the fiber as having performed work. - // This may be unset if the props are determined to be equal later (memo). - didReceiveUpdate = true; - } else if (!includesSomeLane(renderLanes, updateLanes)) { - didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering - // the begin phase. There's still some bookkeeping we that needs to be done - // in this optimized path, mostly pushing stuff onto the stack. + if (current === null) { + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); + var primaryChildFragment = workInProgress.child; + primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return fallbackFragment; + } else if (typeof nextProps.unstable_expectedLoadTime === "number") { + // This is a CPU-bound tree. Skip this tree and show a placeholder to + // unblock the surrounding content. Then immediately retry after the + // initial commit. + var _fallbackFragment = mountSuspenseFallbackChildren( + workInProgress, + nextPrimaryChildren, + nextFallbackChildren, + renderLanes + ); - case HostComponent: - pushHostContext(workInProgress); - break; + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; // Since nothing actually suspended, there will nothing to ping this to + // get it started back up to attempt the next item. While in terms of + // priority this work has the same priority as this current render, it's + // not part of the same transition once the transition has committed. If + // it's sync, we still want to yield so that it can be painted. + // Conceptually, this is really the same as pinging. We can use any + // RetryLane even if it's the one currently rendering since we're leaving + // it behind on this node. - case ClassComponent: { - var Component = workInProgress.type; + workInProgress.lanes = SomeRetryLane; + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren); + } + } else { + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - break; - } + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes + ); - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + var _primaryChildFragment3 = workInProgress.child; + var prevOffscreenState = current.child.memoizedState; + _primaryChildFragment3.memoizedState = + prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(prevOffscreenState, renderLanes); + _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment; + } else { + var _nextPrimaryChildren3 = nextProps.children; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - pushProvider(workInProgress, context, newValue); - break; - } + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes + ); - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + workInProgress.memoizedState = null; + return _primaryChildFragment4; + } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - if (hasChildWork) { - workInProgress.flags |= Update; - } + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes + ); - { - // Reset effect durations for the next eventual effect phase. - // These are reset during render to allow the DevTools commit hook a chance to read them, - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } - } + var _primaryChildFragment5 = workInProgress.child; + var _prevOffscreenState = current.child.memoizedState; + _primaryChildFragment5.memoizedState = + _prevOffscreenState === null + ? mountSuspenseOffscreenState(renderLanes) + : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes); + _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree( + current, + renderLanes + ); // Skip the primary children, and continue working on the + // fallback children. - break; + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; + + var _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + renderLanes + ); - case SuspenseComponent: { - var state = workInProgress.memoizedState; + workInProgress.memoizedState = null; + return _primaryChildFragment6; + } + } + } +} - if (state !== null) { - // whether to retry the primary children, or to skip over it and - // go straight to the fallback. Check the priority of the primary - // child fragment. +function mountSuspensePrimaryChildren( + workInProgress, + primaryChildren, + renderLanes +) { + var mode = workInProgress.mode; + var primaryChildProps = { + mode: "visible", + children: primaryChildren + }; + var primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + primaryChildFragment.return = workInProgress; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; - if (includesSomeLane(renderLanes, primaryChildLanes)) { - // The primary children have pending work. Use the normal path - // to attempt to render the primary children again. - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - } else { - // The primary child fragment does not have pending work marked - // on it - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); // The primary children do not have pending work with sufficient - // priority. Bailout. - - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + if ( + (mode & ConcurrentMode) === NoMode && + progressedPrimaryFragment !== null + ) { + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - // Note: We can return `null` here because we already checked - // whether there were nested context consumers, via the call to - // `bailoutOnAlreadyFinishedWork` above. - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = 0; + primaryChildFragment.treeBaseDuration = 0; + } - break; - } + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = mountWorkInProgressOffscreenFiber( + primaryChildProps, + mode + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) { + // The props argument to `createFiberFromOffscreen` is `any` typed, so we use + // this wrapper function to constrain it. + return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null); +} - if (didSuspendBefore) { - if (_hasChildWork) { - // If something was in fallback state last time, and we have all the - // same children then we're still in progressive loading state. - // Something might get unblocked by state updates or retries in the - // tree which will affect the tail. So we need to use the normal - // path to compute the correct tail. - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - } // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. +function updateWorkInProgressOffscreenFiber(current, offscreenProps) { + // The props argument to `createWorkInProgress` is `any` typed, so we use this + // wrapper function to constrain it. + return createWorkInProgress(current, offscreenProps); +} - workInProgress.flags |= DidCapture; - } // If nothing suspended before and we're rendering the same children, - // then the tail doesn't matter. Anything new that suspends will work - // in the "together" mode, so we can continue from the state we had. - - var renderState = workInProgress.memoizedState; - - if (renderState !== null) { - // Reset to the "together" mode in case we've started a different - // update in the past but didn't complete it. - renderState.rendering = null; - renderState.tail = null; - renderState.lastEffect = null; - } +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } - if (_hasChildWork) { - break; - } else { - // If none of the children had any work, that means that none of - // them got retried so they'll still be blocked in the same way - // as before. We can fast bail out. - return null; - } - } + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - case OffscreenComponent: - case LegacyHiddenComponent: { - // Need to check if the tree still needs to be deferred. This is - // almost identical to the logic used in the normal update path, - // so we'll just enter that. The only difference is we'll bail out - // at the next level instead of this one, because the child props - // have not changed. Which is fine. - // TODO: Probably should refactor `beginWork` to split the bailout - // path from the normal path. I'm tempted to do a labeled break here - // but I won't :) - workInProgress.lanes = NoLanes; - return updateOffscreenComponent(current, workInProgress, renderLanes); - } - } + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; } else { - if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { - // This is a special case that only exists for legacy mode. - // See https://github.com/facebook/react/pull/19216. - didReceiveUpdate = true; - } else { - // An update was scheduled on this fiber, but there are no new props - // nor legacy context. Set this to false. If an update queue or context - // consumer produces a changed value, it will set this to true. Otherwise, - // the component will assume the children have not changed and bail out. - didReceiveUpdate = false; - } + deletions.push(currentFallbackChildFragment); } - } else { - didReceiveUpdate = false; - } // Before entering the begin phase, clear pending update priority. - // TODO: This assumes that we're about to evaluate the component and process - // the update queue. However, there's an exception: SimpleMemoComponent - // sometimes bails out later in the begin phase. This indicates that we should - // move this assignment out of the common path and into each branch. + } - workInProgress.lanes = NoLanes; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } +function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was + // already cloned. In legacy mode, the only case where this isn't true is + // when DevTools forces us to display a fallback; we skip the first render + // pass entirely and go straight to rendering the fallback. (In Concurrent + // Mode, SuspenseList can also trigger this scenario, but this is a legacy- + // only codepath.) + workInProgress.child !== currentPrimaryChildFragment + ) { + var progressedPrimaryFragment = workInProgress.child; + primaryChildFragment = progressedPrimaryFragment; + primaryChildFragment.childLanes = NoLanes; + primaryChildFragment.pendingProps = primaryChildProps; - case FunctionComponent: { - var _Component = workInProgress.type; - var unresolvedProps = workInProgress.pendingProps; - var resolvedProps = - workInProgress.elementType === _Component - ? unresolvedProps - : resolveDefaultProps(_Component, unresolvedProps); - return updateFunctionComponent( - current, - workInProgress, - _Component, - resolvedProps, - renderLanes - ); + if (workInProgress.mode & ProfileMode) { + // Reset the durations from the first pass so they aren't included in the + // final amounts. This seems counterintuitive, since we're intentionally + // not measuring part of the render phase, but this makes it match what we + // do in Concurrent Mode. + primaryChildFragment.actualDuration = 0; + primaryChildFragment.actualStartTime = -1; + primaryChildFragment.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration; + primaryChildFragment.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration; } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; - - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); - - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // We need to complete it now, because we're going to skip over its normal + // complete phase and go straight to rendering the fallback. + var currentOffscreenContainer = currentPrimaryChildFragment.child; + var offscreenContainer = primaryChildFragment.child; + var containerProps = getOffscreenContainerProps(); + offscreenContainer.pendingProps = containerProps; + offscreenContainer.memoizedProps = containerProps; + completeSuspendedOffscreenHostContainer( + currentOffscreenContainer, + offscreenContainer ); - } - - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); - - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + } // The fallback fiber was added as a deletion during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. - case HostText: - return updateHostText(); + workInProgress.deletions = null; + } else { + primaryChildFragment = updateWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + if (enablePersistentOffscreenHostContainer && supportsPersistence) { + // In persistent mode, the offscreen children are wrapped in a host node. + // We need to complete it now, because we're going to skip over its normal + // complete phase and go straight to rendering the fallback. + var _currentOffscreenContainer = currentPrimaryChildFragment.child; - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + if (_currentOffscreenContainer !== null) { + var _offscreenContainer = reconcileOffscreenHostContainer( + currentPrimaryChildFragment, + primaryChildFragment + ); - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + _offscreenContainer.memoizedProps = _offscreenContainer.pendingProps; + completeSuspendedOffscreenHostContainer( + _currentOffscreenContainer, + _offscreenContainer + ); + } + } // Since we're reusing a current tree, we need to reuse the flags, too. + // (We don't do this in legacy mode, because in legacy mode we don't re-use + // the current tree; see previous branch.) - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); - } + var fallbackChildFragment; - case Fragment: - return updateFragment(current, workInProgress, renderLanes); + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + ); + } else { + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); // Needs a placement effect because the parent (the Suspense boundary) already + // mounted but this is a new fiber. - case Mode: - return updateMode(current, workInProgress, renderLanes); + fallbackChildFragment.flags |= Placement; + } - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); +function propagateSuspenseContextChange( + workInProgress, + firstChild, + renderLanes +) { + // Mark any Suspense boundaries with fallbacks as having work to do. + // If they were previously forced into fallbacks, they may now be able + // to unblock. + var node = firstChild; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentNameFromType(_type2) - ); - } - } + if (state !== null) { + scheduleWorkOnFiber(node, renderLanes); } - - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); + } else if (node.tag === SuspenseListComponent) { + // If the tail is hidden there might not be an Suspense boundaries + // to schedule work on. In this case we have to schedule it on the + // list itself. + // We don't have to traverse to the children of the list since + // the list will propagate the change when it rerenders. + scheduleWorkOnFiber(node, renderLanes); + } else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); + if (node === workInProgress) { + return; } - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; - - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); + node = node.return; } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + node.sibling.return = node.return; + node = node.sibling; + } +} - case ScopeComponent: { - break; - } +function findLastContentRow(firstChild) { + // This is going to find the last row among these children that is already + // showing content on the screen, as opposed to being in fallback state or + // new. If a row has multiple Suspense boundaries, any of them being in the + // fallback state, counts as the whole row being in a fallback state. + // Note that the "rows" will be workInProgress, but any nested children + // will still be current since we haven't rendered them yet. The mounted + // order may not be the same as the new order. We use the new order. + var row = firstChild; + var lastContentRow = null; - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } - } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + row = row.sibling; } -} -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; + return lastContentRow; } -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + if (typeof revealOrder === "string") { + switch (revealOrder.toLowerCase()) { + case "together": + case "forwards": + case "backwards": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'Use lowercase "%s" instead.', + revealOrder, + revealOrder.toLowerCase() + ); -{ - // Mutation mode - appendAllChildren = function( - parent, - workInProgress, - needsVisibilityToggle, - isHidden - ) { - // We only have the top Fiber that was created but we need recurse down its - // children to find all the terminal nodes. - var node = workInProgress.child; + break; + } - while (node !== null) { - if (node.tag === HostComponent || node.tag === HostText) { - appendInitialChild(parent, node.stateNode); - } else if (node.tag === HostPortal); - else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } + case "forward": + case "backward": { + error( + '"%s" is not a valid value for revealOrder on . ' + + 'React uses the -s suffix in the spelling. Use "%ss" instead.', + revealOrder, + revealOrder.toLowerCase() + ); - if (node === workInProgress) { - return; - } + break; + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } +} - node = node.return; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; + + error( + '"%s" is not a supported value for tail on . ' + + 'Did you mean "collapsed" or "hidden"?', + tailMode + ); + } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { + didWarnAboutTailOptions[tailMode] = true; + + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); } + } + } +} + +function validateSuspenseListNestedChild(childSlot, index) { + { + var isAnArray = isArray(childSlot); + var isIterable = + !isAnArray && typeof getIteratorFn(childSlot) === "function"; - node.sibling.return = node.return; - node = node.sibling; - } - }; + if (isAnArray || isIterable) { + var type = isAnArray ? "array" : "iterable"; - updateHostContainer = function(current, workInProgress) { - // Noop - }; + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - updateHostComponent$1 = function( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ) { - // If we have an alternate, that means this is an update and we need to - // schedule a side-effect to do the updates. - var oldProps = current.memoizedProps; + return false; + } + } - if (oldProps === newProps) { - // In mutation mode, this is sufficient for a bailout because - // we won't touch this node even if children changed. - return; - } // If we get updated because one of our children updated, we don't - // have newProps so we'll have to reuse them. - // TODO: Split the update API as separate for the props vs. children. - // Even better would be if children weren't special cased at all tho. + return true; +} - var instance = workInProgress.stateNode; - var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host - // component is hitting the resume path. Figure out why. Possibly - // related to `hidden`. +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there - // is a new ref we mark this as an update. All the work is done in commitWork. + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - if (updatePayload) { - markUpdate(workInProgress); - } - }; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - updateHostText$1 = function(current, workInProgress, oldText, newText) { - // If the text differs, mark it as an update. All the work in done in commitWork. - if (oldText !== newText) { - markUpdate(workInProgress); + _i++; + } + } + } else { + error( + 'A single row was passed to a . ' + + "This is not useful since it needs multiple rows. " + + "Did you mean to pass multiple children or an array?", + revealOrder + ); + } + } } - }; + } } -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var tailNode = renderState.tail; - var lastTailNode = null; +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }; + } else { + // We can reuse the existing object from previous renders. + renderState.isBackwards = isBackwards; + renderState.rendering = null; + renderState.renderingStartTime = 0; + renderState.last = lastContentRow; + renderState.tail = tail; + renderState.tailMode = tailMode; + } +} // This can end up rendering this component multiple passes. +// The first pass splits the children fibers into two sets. A head and tail. +// We first render the head. If anything is in fallback state, we do another +// pass through beginWork to rerender all children (including the tail) with +// the force suspend context. If the first render didn't have anything in +// in fallback state. Then we render each row in the tail one-by-one. +// That happens in the completeWork phase without going back to beginWork. - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var revealOrder = nextProps.revealOrder; + var tailMode = nextProps.tail; + var newChildren = nextProps.children; + validateRevealOrder(revealOrder); + validateTailOptions(tailMode, revealOrder); + validateSuspenseListChildren(newChildren, revealOrder); + reconcileChildren(current, workInProgress, newChildren, renderLanes); + var suspenseContext = suspenseStackCursor.current; + var shouldForceFallback = hasSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); - if (lastTailNode === null) { - // All remaining items in the tail are insertions. - renderState.tail = null; - } else { - // Detach the insertion after the last node that was already - // inserted. - lastTailNode.sibling = null; - } + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - break; + if (didSuspendBefore) { + // If we previously forced a fallback, we need to schedule work + // on any nested boundaries to let them know to try to render + // again. This is the same as context updating. + propagateSuspenseContextChange( + workInProgress, + workInProgress.child, + renderLanes + ); } - case "collapsed": { - // Any insertions at the end of the tail list after this point - // should be invisible. If there are already mounted boundaries - // anything before them are not considered for collapsing. - // Therefore we need to go through the whole tail to find if - // there are any. - var _tailNode = renderState.tail; - var _lastTailNode = null; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + pushSuspenseContext(workInProgress, suspenseContext); - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy mode, SuspenseList doesn't work so we just + // use make it a noop by treating it as the default revealOrder. + workInProgress.memoizedState = null; + } else { + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; - if (_lastTailNode === null) { - // All remaining items in the tail are insertions. - if (!hasRenderedATailFallback && renderState.tail !== null) { - // We suspended during the head. We want to show at least one - // row at the tail. So we'll keep on and cut off the rest. - renderState.tail.sibling = null; + if (lastContentRow === null) { + // The whole list is part of the tail. + // TODO: We could fast path by just rendering the tail now. + tail = workInProgress.child; + workInProgress.child = null; } else { - renderState.tail = null; + // Disconnect the tail rows after the content row. + // We're going to render them separately later. + tail = lastContentRow.sibling; + lastContentRow.sibling = null; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode + ); + break; } - break; - } - } -} + case "backwards": { + // We're going to find the first row that has existing content. + // At the same time we're going to reverse the list of everything + // we pass in the meantime. That's going to be our tail in reverse + // order. + var _tail = null; + var row = workInProgress.child; + workInProgress.child = null; + + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - if (!didBailout) { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var actualDuration = completedWork.actualDuration; - var treeBaseDuration = completedWork.selfBaseDuration; - var child = completedWork.child; + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode ); - subtreeFlags |= child.subtreeFlags; - subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will - // only be updated if work is done on the fiber (i.e. it doesn't bailout). - // When work is done, it should bubble to the parent's actualDuration. If - // the fiber has not been cloned though, (meaning no work was done), then - // this value will reflect the amount of time spent working on a previous - // render. In that case it should not bubble. We determine whether it was - // cloned by comparing the child pointer. - - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; + break; } - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined ); - subtreeFlags |= _child.subtreeFlags; - subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. + break; + } - _child.return = completedWork; - _child = _child.sibling; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; } } + } - completedWork.subtreeFlags |= subtreeFlags; - } else { - // Bubble up the earliest expiration time. - if ((completedWork.mode & ProfileMode) !== NoMode) { - // In profiling mode, resetChildExpirationTime is also used to reset - // profiler durations. - var _treeBaseDuration = completedWork.selfBaseDuration; - var _child2 = completedWork.child; + return workInProgress.child; +} - while (_child2 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child2.lanes, _child2.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; - } + if (current === null) { + // Portals are special because we don't append the children during mount + // but at commit. Therefore we need to track insertions which the normal + // flow doesn't do during mount. This doesn't happen at the root because + // the root always starts with a "current" with a null child. + // TODO: Consider unifying this with how the root works. + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + } else { + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + } - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; + return workInProgress.child; +} - while (_child3 !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child3.lanes, _child3.childLanes) - ); // "Static" flags share the lifetime of the fiber/hook they belong to, - // so we should bubble those up even during a bailout. All the other - // flags have a lifetime only of a single render + commit, so we should - // ignore them. +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - subtreeFlags |= _child3.subtreeFlags & StaticMask; - subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code - // smell because it assumes the commit phase is never concurrent with - // the render phase. Will address during refactor to alternate model. +function updateContextProvider(current, workInProgress, renderLanes) { + var providerType = workInProgress.type; + var context = providerType._context; + var newProps = workInProgress.pendingProps; + var oldProps = workInProgress.memoizedProps; + var newValue = newProps.value; - _child3.return = completedWork; - _child3 = _child3.sibling; + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; + + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); } } - completedWork.subtreeFlags |= subtreeFlags; - } - - completedWork.childLanes = newChildLanes; - return didBailout; -} + var providerPropTypes = workInProgress.type.propTypes; -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } + } - switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - bubbleProperties(workInProgress); - return null; + pushProvider(workInProgress, context, newValue); - case ClassComponent: { - var Component = workInProgress.type; + { + if (oldProps !== null) { + var oldValue = oldProps.value; - if (isContextProvider(Component)) { - popContext(workInProgress); + if (objectIs(oldValue, newValue)) { + // No change. Bailout early if children are the same. + if (oldProps.children === newProps.children && !hasContextChanged()) { + return bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + } + } else { + // The context value changed. Search for matching consumers and schedule + // them to update. + propagateContextChange(workInProgress, context, renderLanes); } - - bubbleProperties(workInProgress); - return null; } + } - case HostRoot: { - var fiberRoot = workInProgress.stateNode; + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); +var hasWarnedAboutUsingContextAsConsumer = false; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } +function updateContextConsumer(current, workInProgress, renderLanes) { + var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In + // DEV mode, we create a separate object for Context.Consumer that acts + // like a proxy to Context. This proxy object adds unnecessary code in PROD + // so we use the old behaviour (Context.Consumer references Context) to + // reduce size and overhead. The separate object references context via + // a property called "_context", which also gives us the ability to check + // in DEV mode if this property exists or not and warn if it does not. - if (current === null || current.child === null) { - // If we hydrated, pop so that we can delete any remaining children - // that weren't hydrated. - var wasHydrated = popHydrationState(); + { + if (context._context === undefined) { + // This may be because it's a Context (rather than a Consumer). + // Or it may be because it's older React where they're the same thing. + // We only want to warn if we're sure it's a new React. + if (context !== context.Consumer) { + if (!hasWarnedAboutUsingContextAsConsumer) { + hasWarnedAboutUsingContextAsConsumer = true; - if (wasHydrated) { - // If we hydrated, then we'll need to schedule an update for - // the commit side-effects on the root. - markUpdate(workInProgress); - } else if (!fiberRoot.hydrate) { - // Schedule an effect to clear this container at the start of the next commit. - // This handles the case of React rendering into a container with previous children. - // It's also safe to do for updates too, because current.child would only be null - // if the previous render was null (so the the container would already be empty). - workInProgress.flags |= Snapshot; + error( + "Rendering directly is not supported and will be removed in " + + "a future major release. Did you mean to render instead?" + ); } } - - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); - return null; + } else { + context = context._context; } + } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + var newProps = workInProgress.pendingProps; + var render = newProps.children; - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + { + if (typeof render !== "function") { + error( + "A context consumer was rendered with multiple children, or a child " + + "that isn't a function. A context consumer expects a single child " + + "that is a function. If you did pass a function, make sure there " + + "is no trailing or leading whitespace around it." + ); + } + } - if (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); - } - } else { - if (!newProps) { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context); - bubbleProperties(workInProgress); - return null; - } + var newChildren; - var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context - // "stack" as the parent. Then append children as we go in beginWork - // or completeWork depending on whether we want to add them top->down or - // bottom->up. Top->down is faster in IE11. + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } - var _wasHydrated = popHydrationState(); + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - if (_wasHydrated) { - // TODO: Move this and createInstance step into the beginPhase - // to consolidate. - if (prepareToHydrateHostInstance()) { - // If changes to the hydrated node need to be applied at the - // commit-phase we mark this as such. - markUpdate(workInProgress); - } - } else { - var instance = createInstance( - type, - newProps, - rootContainerInstance, - currentHostContext, - workInProgress - ); - appendAllChildren(instance, workInProgress, false, false); - workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount. - // (eg DOM renderer supports auto-focus for certain elements). - // Make sure such renderers get scheduled for later work. +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - if (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - bubbleProperties(workInProgress); + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + + if (!includesSomeLane(renderLanes, workInProgress.childLanes)) { + // The children don't have any work either. We can skip them. + // TODO: Once we add back resuming, we should check if the children are + // a work-in-progress set. If so, we need to transfer their effects. + { return null; } + } // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. - case HostText: { - var newText = newProps; + cloneChildFibers(current, workInProgress); + return workInProgress.child; +} - if (current && workInProgress.stateNode != null) { - var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need - // to schedule a side-effect to do the updates. +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - updateHostText$1(current, workInProgress, oldText, newText); - } else { - if (typeof newText !== "string") { - if (!(workInProgress.stateNode !== null)) { - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - } // This can happen when we abort work. - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - var _rootContainerInstance = getRootHostContainer(); + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - var _currentHostContext = getHostContext(); + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - var _wasHydrated2 = popHydrationState(); + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } + + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); } } - bubbleProperties(workInProgress); - return null; + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. + + var deletions = returnFiber.deletions; + + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + return newWorkInProgress; + } +} - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. +function checkScheduledUpdateOrContext(current, renderLanes) { + // Before performing an early bailout, we must check if there are pending + // updates or context. + var updateLanes = current.lanes; - return workInProgress; - } + if (includesSomeLane(updateLanes, renderLanes)) { + return true; + } // No pending update, but because context is propagated lazily, we need - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + return false; +} - if (current === null); - else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; - } // If the suspended state of the boundary changes, we need to schedule - // an effect to toggle the subtree's visibility. When we switch from - // fallback -> primary, the inner Offscreen fiber schedules this effect - // as part of its normal complete phase. But when we switch from - // primary -> fallback, the inner Offscreen fiber does not have a complete - // phase. So we need to schedule its effect here. - // - // We also use this flag to connect/disconnect the effects, but the same - // logic applies: when re-connecting, the Offscreen fiber's complete - // phase will handle scheduling the effect. It's only when the fallback - // is active that we have to do anything special. +function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes +) { + // This fiber does not have any pending work. Bailout without entering + // the begin phase. There's still some bookkeeping we that needs to be done + // in this optimized path, mostly pushing stuff onto the stack. + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - if (nextDidTimeout && !prevDidTimeout) { - var offscreenFiber = workInProgress.child; - offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything - // in the concurrent tree already suspended during this render. - // This is a known bug. + case HostComponent: + pushHostContext(workInProgress); + break; - if ((workInProgress.mode & ConcurrentMode) !== NoMode) { - // TODO: Move this back to throwException because this is too late - // if this is a large tree which is common for initial loads. We - // don't know if we should restart a render or not until we get - // this marker, and this is too late. - // If this render already had a ping or lower pri updates, - // and this is the first time we know we're going to suspend we - // should be able to immediately restart from within throwException. - var hasInvisibleChildContext = - current === null && - workInProgress.memoizedProps.unstable_avoidThisFallback !== true; + case ClassComponent: { + var Component = workInProgress.type; - if ( - hasInvisibleChildContext || - hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ) - ) { - // If this was in an invisible tree or a new render, then showing - // this boundary is ok. - renderDidSuspend(); - } else { - // Otherwise, we're going to have to hide content so we should - // suspend for longer if possible. - renderDidSuspendDelayIfPossible(); - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } + + break; + } + + case HostPortal: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; + + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + var context = workInProgress.type._context; + pushProvider(workInProgress, context, newValue); + break; + } + + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + if (hasChildWork) { + workInProgress.flags |= Update; + } + + { + // Reset effect durations for the next eventual effect phase. + // These are reset during render to allow the DevTools commit hook a chance to read them, + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } } - var wakeables = workInProgress.updateQueue; + break; - if (wakeables !== null) { - // Schedule an effect to attach a retry listener to the promise. - // TODO: Move to passive phase - workInProgress.flags |= Update; - } + case SuspenseComponent: { + var state = workInProgress.memoizedState; - bubbleProperties(workInProgress); + if (state !== null) { + // whether to retry the primary children, or to skip over it and + // go straight to the fallback. Check the priority of the primary + // child fragment. - { - if ((workInProgress.mode & ProfileMode) !== NoMode) { - if (nextDidTimeout) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var _primaryChildFragment2 = workInProgress.child; + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - if (_primaryChildFragment2 !== null) { - // $FlowFixMe Flow doesn't support type casting in combination with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } + if (includesSomeLane(renderLanes, primaryChildLanes)) { + // The primary children have pending work. Use the normal path + // to attempt to render the primary children again. + return updateSuspenseComponent(current, workInProgress, renderLanes); + } else { + // The primary child fragment does not have pending work marked + // on it + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); // The primary children do not have pending work with sufficient + // priority. Bailout. + + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + // Note: We can return `null` here because we already checked + // whether there were nested context consumers, via the call to + // `bailoutOnAlreadyFinishedWork` above. + return null; } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } - return null; + break; } - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - bubbleProperties(workInProgress); - return null; + if (didSuspendBefore) { + if (_hasChildWork) { + // If something was in fallback state last time, and we have all the + // same children then we're still in progressive loading state. + // Something might get unblocked by state updates or retries in the + // tree which will affect the tail. So we need to use the normal + // path to compute the correct tail. + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + } // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; + workInProgress.flags |= DidCapture; + } // If nothing suspended before and we're rendering the same children, + // then the tail doesn't matter. Anything new that suspends will work + // in the "together" mode, so we can continue from the state we had. - case IncompleteClassComponent: { - // Same as class component case. I put it down here so that the tags are - // sequential to ensure this switch is compiled to a jump table. - var _Component = workInProgress.type; + var renderState = workInProgress.memoizedState; - if (isContextProvider(_Component)) { - popContext(workInProgress); + if (renderState !== null) { + // Reset to the "together" mode in case we've started a different + // update in the past but didn't complete it. + renderState.rendering = null; + renderState.tail = null; + renderState.lastEffect = null; } - bubbleProperties(workInProgress); - return null; + pushSuspenseContext(workInProgress, suspenseStackCursor.current); + + if (_hasChildWork) { + break; + } else { + // If none of the children had any work, that means that none of + // them got retried so they'll still be blocked in the same way + // as before. We can fast bail out. + return null; + } } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + case OffscreenComponent: + case LegacyHiddenComponent: { + // Need to check if the tree still needs to be deferred. This is + // almost identical to the logic used in the normal update path, + // so we'll just enter that. The only difference is we'll bail out + // at the next level instead of this one, because the child props + // have not changed. Which is fine. + // TODO: Probably should refactor `beginWork` to split the bailout + // path from the normal path. I'm tempted to do a labeled break here + // but I won't :) + workInProgress.lanes = NoLanes; + return updateOffscreenComponent(current, workInProgress, renderLanes); + } + } - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); +} + +function beginWork(current, workInProgress, renderLanes) { + { + if (workInProgress._debugNeedsRemount && current !== null) { + // This will restart the begin phase with a new fiber. + return remountFiber( + current, + workInProgress, + createFiberFromTypeAndProps( + workInProgress.type, + workInProgress.key, + workInProgress.pendingProps, + workInProgress._debugOwner || null, + workInProgress.mode, + workInProgress.lanes + ) + ); + } + } + + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; + + if ( + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type + ) { + // If props or context changed, mark the fiber as having performed work. + // This may be unset if the props are determined to be equal later (memo). + didReceiveUpdate = true; + } else { + // Neither props nor legacy context changes. Check if there's a pending + // update or context change. + var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext( + current, + renderLanes + ); + + if ( + !hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there + // may not be work scheduled on `current`, so we check for this flag. + (workInProgress.flags & DidCapture) === NoFlags + ) { + // No pending updates or context. Bail out now. + didReceiveUpdate = false; + return attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) { + // This is a special case that only exists for legacy mode. + // See https://github.com/facebook/react/pull/19216. + didReceiveUpdate = true; + } else { + // An update was scheduled on this fiber, but there are no new props + // nor legacy context. Set this to false. If an update queue or context + // consumer produces a changed value, it will set this to true. Otherwise, + // the component will assume the children have not changed and bail out. + didReceiveUpdate = false; + } + } + } else { + didReceiveUpdate = false; + } // Before entering the begin phase, clear pending update priority. + // TODO: This assumes that we're about to evaluate the component and process + // the update queue. However, there's an exception: SimpleMemoComponent + // sometimes bails out later in the begin phase. This indicates that we should + // move this assignment out of the common path and into each branch. - if (renderedTail === null) { - // We just rendered the head. - if (!didSuspendAlready) { - // This is the first pass. We need to figure out if anything is still - // suspended in the rendered set. - // If new content unsuspended, but there's still some content that - // didn't. Then we need to do a second pass that forces everything - // to keep showing their fallbacks. - // We might be suspended if something in this render pass suspended, or - // something in the previous committed pass suspended. Otherwise, - // there's no chance so we can skip the expensive call to - // findFirstSuspended. - var cannotBeSuspended = - renderHasNotSuspendedYet() && - (current === null || (current.flags & DidCapture) === NoFlags); + workInProgress.lanes = NoLanes; - if (!cannotBeSuspended) { - var row = workInProgress.child; + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - while (row !== null) { - var suspended = findFirstSuspended(row); + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + renderLanes + ); + } - if (suspended !== null) { - didSuspendAlready = true; - workInProgress.flags |= DidCapture; - cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as - // part of the second pass. In that case nothing will subscribe to - // its thennables. Instead, we'll transfer its thennables to the - // SuspenseList so that it can retry if they resolve. - // There might be multiple of these in the list but since we're - // going to wait for all of them anyway, it doesn't really matter - // which ones gets to ping. In theory we could get clever and keep - // track of how many dependencies remain but it gets tricky because - // in the meantime, we can add/remove/change items and dependencies. - // We might bail out of the loop before finding any but that - // doesn't matter since that means that the other boundaries that - // we did find already has their listeners attached. + case FunctionComponent: { + var Component = workInProgress.type; + var unresolvedProps = workInProgress.pendingProps; + var resolvedProps = + workInProgress.elementType === Component + ? unresolvedProps + : resolveDefaultProps(Component, unresolvedProps); + return updateFunctionComponent( + current, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + } - var newThennables = suspended.updateQueue; + case ClassComponent: { + var _Component = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (newThennables !== null) { - workInProgress.updateQueue = newThennables; - workInProgress.flags |= Update; - } // Rerender the whole list, but this time, we'll force fallbacks - // to stay in place. - // Reset the effect flags before doing the second pass since that's now invalid. - // Reset the child fibers to their original state. + var _resolvedProps = + workInProgress.elementType === _Component + ? _unresolvedProps + : resolveDefaultProps(_Component, _unresolvedProps); + + return updateClassComponent( + current, + workInProgress, + _Component, + _resolvedProps, + renderLanes + ); + } + + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + case HostComponent: + return updateHostComponent$1(current, workInProgress, renderLanes); - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. + case HostText: + return updateHostText$1(); - return workInProgress.child; - } + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - row = row.sibling; - } - } + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - if (renderState.tail !== null && now() > getRenderTargetTime()) { - // We have already passed our CPU deadline but we still have rows - // left in the tail. We'll just give up further attempts to render - // the main content and only render fallbacks. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - workInProgress.lanes = SomeRetryLane; - } - } else { - cutOffTailIfNeeded(renderState, false); - } // Next we're going to render the tail. - } else { - // Append the rendered row to the child list. - if (!didSuspendAlready) { - var _suspended = findFirstSuspended(renderedTail); + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - if (_suspended !== null) { - workInProgress.flags |= DidCapture; - didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't - // get lost if this row ends up dropped during a second pass. + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } - var _newThennables = _suspended.updateQueue; + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; - } + case Mode: + return updateMode(current, workInProgress, renderLanes); - cutOffTailIfNeeded(renderState, true); // This might have been modified. + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We're done. - bubbleProperties(workInProgress); - return null; - } - } else if ( - // The time it took to render last row is greater than the remaining - // time we have to render. So rendering one more row would likely - // exceed it. - now() * 2 - renderState.renderingStartTime > - getRenderTargetTime() && - renderLanes !== OffscreenLane - ) { - // We have now passed our CPU deadline and we'll just give up further - // attempts to render the main content and only render fallbacks. - // The assumption is that this is usually faster. - workInProgress.flags |= DidCapture; - didSuspendAlready = true; - cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this - // to get it started back up to attempt the next item. While in terms - // of priority this work has the same priority as this current render, - // it's not part of the same transition once the transition has - // committed. If it's sync, we still want to yield so that it can be - // painted. Conceptually, this is really the same as pinging. - // We can use any RetryLane even if it's the one currently rendering - // since we're leaving it behind on this node. + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - workInProgress.lanes = SomeRetryLane; - } - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - if (renderState.isBackwards) { - // The effect list of the backwards tail will have been added - // to the end. This breaks the guarantee that life-cycles fire in - // sibling order but that isn't a strong guarantee promised by React. - // Especially since these might also just pop in during future commits. - // Append to the beginning of the list. - renderedTail.sibling = workInProgress.child; - workInProgress.child = renderedTail; - } else { - var previousSibling = renderState.last; + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - renderState.last = renderedTail; + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentNameFromType(_type2) + ); + } } } - if (renderState.tail !== null) { - // We still have tail rows to render. - // Pop a row. - var next = renderState.tail; - renderState.rendering = next; - renderState.tail = next.sibling; - renderState.renderingStartTime = now(); - next.sibling = null; // Restore the context. - // TODO: We can probably just avoid popping it instead and only - // setting it the first time we go from not suspended to suspended. + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + renderLanes + ); + } - var suspenseContext = suspenseStackCursor.current; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + renderLanes + ); + } - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + case IncompleteClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. + var _resolvedProps4 = + workInProgress.elementType === _Component2 + ? _unresolvedProps4 + : resolveDefaultProps(_Component2, _unresolvedProps4); - return next; - } + return mountIncompleteClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps4, + renderLanes + ); + } - bubbleProperties(workInProgress); - return null; + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); } case ScopeComponent: { break; } - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); - var _nextState = workInProgress.memoizedState; - var nextIsHidden = _nextState !== null; - - if (current !== null) { - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" && // LegacyHidden doesn't do any hiding — it only pre-renders. - workInProgress.tag !== LegacyHiddenComponent - ) { - workInProgress.flags |= Visibility; - } - } - - if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) { - bubbleProperties(workInProgress); - } else { - // Don't bubble properties for hidden children unless we're rendering - // at offscreen priority. - if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) { - bubbleProperties(workInProgress); - - { - // Check if there was an insertion or update in the hidden subtree. - // If so, we need to hide those nodes in the commit phase, so - // schedule a visibility effect. - if ( - workInProgress.tag !== LegacyHiddenComponent && - workInProgress.subtreeFlags & (Placement | Update) && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Visibility; - } - } - } - } + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } - return null; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); } } @@ -22320,6 +22499,14 @@ function createFiberFromTypeAndProps( return fiber; } +function createOffscreenHostContainerFiber(props, fiberMode, lanes, key) { + { + // Only implemented in persistent mode + { + throw Error("Not implemented."); + } + } +} function createFiberFromElement(element, mode, lanes) { var owner = null; diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index 43eb09ea3ed134..315e991012b316 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,14 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), - React = require("react"), - Scheduler = require("scheduler"); + React = require("react"); +var Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -1899,7 +1899,7 @@ function lanesToEventPriority(lanes) { : 4 : 1; } -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -3269,7 +3269,7 @@ function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.flags & 128)) return node; @@ -4078,6 +4078,404 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } +var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; +appendAllChildren = function(parent, workInProgress) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +updateHostContainer = function() {}; +updateHostComponent = function(current, workInProgress, type, newProps) { + current.memoizedProps !== newProps && + (requiredContext(contextStackCursor$1.current), + (workInProgress.updateQueue = UPDATE_SIGNAL)) && + (workInProgress.flags |= 4); +}; +updateHostText = function(current, workInProgress, oldText, newText) { + oldText !== newText && (workInProgress.flags |= 4); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$38 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$38 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$38 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$38.sibling = null); + } +} +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$39 = completedWork.child; null !== child$39; ) + (newChildLanes |= child$39.lanes | child$39.childLanes), + (subtreeFlags |= child$39.subtreeFlags & 1835008), + (subtreeFlags |= child$39.flags & 1835008), + (child$39.return = completedWork), + (child$39 = child$39.sibling); + else + for (child$39 = completedWork.child; null !== child$39; ) + (newChildLanes |= child$39.lanes | child$39.childLanes), + (subtreeFlags |= child$39.subtreeFlags), + (subtreeFlags |= child$39.flags), + (child$39.return = completedWork), + (child$39 = child$39.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (newProps = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + newProps.pendingContext && + ((newProps.context = newProps.pendingContext), + (newProps.pendingContext = null)), + (null !== current && null !== current.child) || + newProps.hydrate || + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent( + current, + workInProgress, + type, + newProps, + renderLanes + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = allocateTag(); + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + current, + type.uiViewClassName, + renderLanes, + updatePayload + ); + renderLanes = new ReactNativeFiberHostComponent( + current, + type, + workInProgress + ); + instanceCache.set(current, workInProgress); + instanceProps.set(current, newProps); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + renderLanes = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + renderLanes, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.flags & 128)) + return (workInProgress.lanes = renderLanes), workInProgress; + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if ( + null !== newProps && + !renderLanes && + ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) + ) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3); + else { + if ( + 0 === workInProgressRootExitStatus || + 3 === workInProgressRootExitStatus + ) + workInProgressRootExitStatus = 4; + null === workInProgressRoot || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || + markRootSuspended$1( + workInProgressRoot, + workInProgressRootRenderLanes + ); + } + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (newProps = workInProgress.child; null !== newProps; ) + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 1835010), + (updatePayload = renderLanes.alternate), + null === updatePayload + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = type), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null)) + : ((renderLanes.childLanes = updatePayload.childLanes), + (renderLanes.lanes = updatePayload.lanes), + (renderLanes.child = updatePayload.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = + updatePayload.memoizedProps), + (renderLanes.memoizedState = + updatePayload.memoizedState), + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type + ? null + : { + lanes: type.lanes, + firstContext: type.firstContext + })), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + "unstable-defer-without-hiding" !== newProps.mode && + 23 !== workInProgress.tag && + (workInProgress.flags |= 4096), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + (bubbleProperties(workInProgress), + 23 !== workInProgress.tag && + workInProgress.subtreeFlags & 6 && + "unstable-defer-without-hiding" !== newProps.mode && + (workInProgress.flags |= 4096)) + : bubbleProperties(workInProgress), + null + ); + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, didReceiveUpdate = !1; function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { @@ -4125,7 +4523,6 @@ function updateMemoComponent( workInProgress, Component, nextProps, - updateLanes, renderLanes ) { if (null === current) { @@ -4145,7 +4542,6 @@ function updateMemoComponent( workInProgress, type, nextProps, - updateLanes, renderLanes ) ); @@ -4162,14 +4558,13 @@ function updateMemoComponent( return (workInProgress.child = current); } type = current.child; - if ( - 0 === (updateLanes & renderLanes) && - ((updateLanes = type.memoizedProps), - (Component = Component.compare), - (Component = null !== Component ? Component : shallowEqual), - Component(updateLanes, nextProps) && current.ref === workInProgress.ref) - ) - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + if (0 === (current.lanes & renderLanes)) { + var prevProps = type.memoizedProps; + Component = Component.compare; + Component = null !== Component ? Component : shallowEqual; + if (Component(prevProps, nextProps) && current.ref === workInProgress.ref) + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } workInProgress.flags |= 1; current = createWorkInProgress(type, nextProps); current.ref = workInProgress.ref; @@ -4181,22 +4576,20 @@ function updateSimpleMemoComponent( workInProgress, Component, nextProps, - updateLanes, renderLanes ) { if ( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) + ) + if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - } return updateFunctionComponent( current, workInProgress, @@ -4249,7 +4642,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { +function markRef$1(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4498,7 +4891,7 @@ function finishClassComponent( hasContext, renderLanes ) { - markRef(current, workInProgress); + markRef$1(current, workInProgress); var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( @@ -4597,7 +4990,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { renderLanes = createFiberFromOffscreen( { mode: "visible", children: current }, workInProgress.mode, - renderLanes, + 0, null ); renderLanes.return = workInProgress; @@ -4891,406 +5284,72 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { } return workInProgress.child; } -var appendAllChildren, - updateHostContainer, - updateHostComponent$1, - updateHostText$1; -appendAllChildren = function(parent, workInProgress) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -updateHostContainer = function() {}; -updateHostComponent$1 = function(current, workInProgress, type, newProps) { - current.memoizedProps !== newProps && - (requiredContext(contextStackCursor$1.current), - (workInProgress.updateQueue = UPDATE_SIGNAL)) && - (workInProgress.flags |= 4); -}; -updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && (workInProgress.flags |= 4); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$69 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$69 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$69 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$69.sibling = null); - } -} -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$70 = completedWork.child; null !== child$70; ) - (newChildLanes |= child$70.lanes | child$70.childLanes), - (subtreeFlags |= child$70.subtreeFlags & 1835008), - (subtreeFlags |= child$70.flags & 1835008), - (child$70.return = completedWork), - (child$70 = child$70.sibling); - else - for (child$70 = completedWork.child; null !== child$70; ) - (newChildLanes |= child$70.lanes | child$70.childLanes), - (subtreeFlags |= child$70.subtreeFlags), - (subtreeFlags |= child$70.flags), - (child$70.return = completedWork), - (child$70 = child$70.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; +function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes +) { switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + pushHostRootContext(workInProgress); + break; case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; - } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, - renderLanes, - updatePayload - ); - renderLanes = new ReactNativeFiberHostComponent( - current, - type, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(renderLanes, workInProgress, !1, !1); - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 256); - } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, - workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - renderLanes = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - renderLanes, - "RCTRawText", + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; + case 4: + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; + case 10: + var context = workInProgress.type._context, + nextValue = workInProgress.memoizedProps.value; + push(valueCursor, context._currentValue); + context._currentValue = nextValue; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent(current, workInProgress, renderLanes); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + current = bailoutOnAlreadyFinishedWork( current, - { text: newProps } + workInProgress, + renderLanes ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; + return null !== current ? current.sibling : null; } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return (workInProgress.lanes = renderLanes), workInProgress; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if ( - null !== newProps && - !renderLanes && - ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) - ) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3); - else { - if ( - 0 === workInProgressRootExitStatus || - 3 === workInProgressRootExitStatus - ) - workInProgressRootExitStatus = 4; - null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || - markRootSuspended$1( - workInProgressRoot, - workInProgressRootRenderLanes - ); - } - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - return null; - case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); - case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 1835010), - (updatePayload = renderLanes.alternate), - null === updatePayload - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = type), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null)) - : ((renderLanes.childLanes = updatePayload.childLanes), - (renderLanes.lanes = updatePayload.lanes), - (renderLanes.child = updatePayload.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = - updatePayload.memoizedProps), - (renderLanes.memoizedState = - updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type - ? null - : { - lanes: type.lanes, - firstContext: type.firstContext - })), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + context = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (context) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (context) break; + else return null; case 22: case 23: return ( - popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== renderLanes && - "unstable-defer-without-hiding" !== newProps.mode && - 23 !== workInProgress.tag && - (workInProgress.flags |= 4096), - renderLanes && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - (bubbleProperties(workInProgress), - 23 !== workInProgress.tag && - workInProgress.subtreeFlags & 6 && - "unstable-defer-without-hiding" !== newProps.mode && - (workInProgress.flags |= 4096)) - : bubbleProperties(workInProgress), - null + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5445,8 +5504,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$82 = effect.create; - effect.destroy = create$82(); + var create$83 = effect.create; + effect.destroy = create$83(); } effect = effect.next; } while (effect !== finishedWork); @@ -5906,8 +5965,8 @@ function commitMutationEffects(root, firstChild) { switch (firstChild.tag) { case 13: if (null !== firstChild.memoizedState) { - var current$87 = firstChild.alternate; - if (null === current$87 || null === current$87.memoizedState) + var current$88 = firstChild.alternate; + if (null === current$88 || null === current$88.memoizedState) globalMostRecentFallbackTime = now(); } break; @@ -6058,8 +6117,8 @@ function commitLayoutEffects(finishedWork) { commitUpdateQueue(firstChild, updateQueue, instance); break; case 3: - var updateQueue$83 = firstChild.updateQueue; - if (null !== updateQueue$83) { + var updateQueue$84 = firstChild.updateQueue; + if (null !== updateQueue$84) { current = null; if (null !== firstChild.child) switch (firstChild.child.tag) { @@ -6069,7 +6128,7 @@ function commitLayoutEffects(finishedWork) { case 1: current = firstChild.child.stateNode; } - commitUpdateQueue(firstChild, updateQueue$83, current); + commitUpdateQueue(firstChild, updateQueue$84, current); } break; case 5: @@ -7120,7 +7179,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; if (null !== current) if ( current.memoizedProps !== workInProgress.pendingProps || @@ -7128,158 +7186,98 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ) didReceiveUpdate = !0; else { - if (0 === (renderLanes & updateLanes)) { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.type._context; - var nextValue = workInProgress.memoizedProps.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = nextValue; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (updateLanes) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; - } - nextValue = workInProgress.memoizedState; - null !== nextValue && - ((nextValue.rendering = null), - (nextValue.tail = null), - (nextValue.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes + if ( + 0 === (current.lanes & renderLanes) && + 0 === (workInProgress.flags & 128) + ) + return ( + (didReceiveUpdate = !1), + attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) ); - } didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { case 2: - updateLanes = workInProgress.type; + var Component = workInProgress.type; null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + var context = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, - updateLanes, + Component, current, - nextValue, + context, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof nextValue && - null !== nextValue && - "function" === typeof nextValue.render && - void 0 === nextValue.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; workInProgress.updateQueue = null; - if (isContextProvider(updateLanes)) { + if (isContextProvider(Component)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== nextValue.state && void 0 !== nextValue.state - ? nextValue.state + null !== context.state && void 0 !== context.state + ? context.state : null; initializeUpdateQueue(workInProgress); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; - mountClassInstance(workInProgress, updateLanes, current, renderLanes); + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; + mountClassInstance(workInProgress, Component, current, renderLanes); workInProgress = finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, hasContext, renderLanes ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, nextValue, renderLanes), + reconcileChildren(null, workInProgress, context, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - nextValue = workInProgress.elementType; + Component = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = nextValue._init; - nextValue = hasContext(nextValue._payload); - workInProgress.type = nextValue; - hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); - current = resolveDefaultProps(nextValue, current); - switch (hasContext) { + context = Component._init; + Component = context(Component._payload); + workInProgress.type = Component; + context = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (context) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7288,7 +7286,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7297,7 +7295,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7306,79 +7304,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), - updateLanes, + Component, + resolveDefaultProps(Component.type, current), renderLanes ); break a; } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + Component + ". Lazy element type must resolve to a class or function." ); } return workInProgress; case 0: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateFunctionComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 1: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateClassComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 3: pushHostRootContext(workInProgress); - updateLanes = workInProgress.updateQueue; - if (null === current || null === updateLanes) + Component = workInProgress.updateQueue; + if (null === current || null === Component) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - nextValue = workInProgress.pendingProps; - updateLanes = workInProgress.memoizedState.element; + context = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, context, null, renderLanes); + context = workInProgress.memoizedState.element; + context === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, context, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: return ( pushHostContext(workInProgress), - (updateLanes = workInProgress.pendingProps.children), - markRef(current, workInProgress), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + (Component = workInProgress.pendingProps.children), + markRef$1(current, workInProgress), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -7391,35 +7388,30 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (updateLanes = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - updateLanes, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - updateLanes, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateForwardRef( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); @@ -7455,16 +7447,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); case 10: a: { - updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + Component = workInProgress.type._context; + context = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - var newValue = nextValue.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = newValue; + var newValue = context.value; + push(valueCursor, Component._currentValue); + Component._currentValue = newValue; if (null !== hasContext) if (objectIs(hasContext.value, newValue)) { if ( - hasContext.children === nextValue.children && + hasContext.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7489,7 +7481,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { null !== dependency; ) { - if (dependency.context === updateLanes) { + if (dependency.context === Component) { if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; @@ -7540,7 +7532,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7548,29 +7540,25 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), - (updateLanes = workInProgress.pendingProps.children), + (context = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context)), + (Component = Component(context)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), - (hasContext = resolveDefaultProps( - nextValue, - workInProgress.pendingProps - )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (Component = workInProgress.type), + (context = resolveDefaultProps(Component, workInProgress.pendingProps)), + (context = resolveDefaultProps(Component.type, context)), updateMemoComponent( current, workInProgress, - nextValue, - hasContext, - updateLanes, + Component, + context, renderLanes ) ); @@ -7580,32 +7568,31 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.type, workInProgress.pendingProps, - updateLanes, renderLanes ); case 17: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)), (workInProgress.tag = 1), - isContextProvider(updateLanes) + isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, Component, context), + mountClassInstance(workInProgress, Component, context, renderLanes), finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, current, renderLanes @@ -8034,10 +8021,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_981 = { + devToolsConfig$jscomp$inline_984 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.0.0-419cc9c37-20210726", + version: "18.0.0-19092ac8c-20210803", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8052,11 +8039,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1228 = { - bundleType: devToolsConfig$jscomp$inline_981.bundleType, - version: devToolsConfig$jscomp$inline_981.version, - rendererPackageName: devToolsConfig$jscomp$inline_981.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_981.rendererConfig, +var internals$jscomp$inline_1237 = { + bundleType: devToolsConfig$jscomp$inline_984.bundleType, + version: devToolsConfig$jscomp$inline_984.version, + rendererPackageName: devToolsConfig$jscomp$inline_984.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_984.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8072,26 +8059,26 @@ var internals$jscomp$inline_1228 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_981.findFiberByHostInstance || + devToolsConfig$jscomp$inline_984.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-419cc9c37-20210726" + reconcilerVersion: "18.0.0-19092ac8c-20210803" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1229 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1238 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1229.isDisabled && - hook$jscomp$inline_1229.supportsFiber + !hook$jscomp$inline_1238.isDisabled && + hook$jscomp$inline_1238.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1229.inject( - internals$jscomp$inline_1228 + (rendererID = hook$jscomp$inline_1238.inject( + internals$jscomp$inline_1237 )), - (injectedHook = hook$jscomp$inline_1229); + (injectedHook = hook$jscomp$inline_1238); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 2c8a86864cfa14..01bfdba8842895 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,14 +7,14 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ "use strict"; require("react-native/Libraries/ReactPrivate/ReactNativePrivateInitializeCore"); var ReactNativePrivateInterface = require("react-native/Libraries/ReactPrivate/ReactNativePrivateInterface"), - React = require("react"), - Scheduler = require("scheduler"); + React = require("react"); +var Scheduler = require("scheduler"); function invokeGuardedCallbackImpl(name, func, context, a, b, c, d, e, f) { var funcArgs = Array.prototype.slice.call(arguments, 3); try { @@ -1947,7 +1947,7 @@ function lanesToEventPriority(lanes) { : 4 : 1; } -function shim() { +function shim$1() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); @@ -3317,7 +3317,7 @@ function findFirstSuspended(row) { for (var node = row; null !== node; ) { if (13 === node.tag) { var state = node.memoizedState; - if (null !== state && (null === state.dehydrated || shim() || shim())) + if (null !== state && (null === state.dehydrated || shim$1() || shim$1())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { if (0 !== (node.flags & 128)) return node; @@ -4184,165 +4184,607 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, - didReceiveUpdate = !1; -function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { - workInProgress.child = - null === current - ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) - : reconcileChildFibers( - workInProgress, - current.child, - nextChildren, - renderLanes - ); -} -function updateForwardRef( - current, - workInProgress, - Component, - nextProps, - renderLanes -) { - Component = Component.render; - var ref = workInProgress.ref; - prepareToReadContext(workInProgress, renderLanes); - nextProps = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - ref, - renderLanes - ); - if (null !== current && !didReceiveUpdate) - return ( - (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), - (current.lanes &= ~renderLanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - workInProgress.flags |= 1; - reconcileChildren(current, workInProgress, nextProps, renderLanes); - return workInProgress.child; +var appendAllChildren, updateHostContainer, updateHostComponent, updateHostText; +appendAllChildren = function(parent, workInProgress) { + for (var node = workInProgress.child; null !== node; ) { + if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); + else if (4 !== node.tag && null !== node.child) { + node.child.return = node; + node = node.child; + continue; + } + if (node === workInProgress) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === workInProgress) return; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } +}; +updateHostContainer = function() {}; +updateHostComponent = function(current, workInProgress, type, newProps) { + current.memoizedProps !== newProps && + (requiredContext(contextStackCursor$1.current), + (workInProgress.updateQueue = UPDATE_SIGNAL)) && + (workInProgress.flags |= 4); +}; +updateHostText = function(current, workInProgress, oldText, newText) { + oldText !== newText && (workInProgress.flags |= 4); +}; +function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { + switch (renderState.tailMode) { + case "hidden": + hasRenderedATailFallback = renderState.tail; + for (var lastTailNode = null; null !== hasRenderedATailFallback; ) + null !== hasRenderedATailFallback.alternate && + (lastTailNode = hasRenderedATailFallback), + (hasRenderedATailFallback = hasRenderedATailFallback.sibling); + null === lastTailNode + ? (renderState.tail = null) + : (lastTailNode.sibling = null); + break; + case "collapsed": + lastTailNode = renderState.tail; + for (var lastTailNode$40 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$40 = lastTailNode), + (lastTailNode = lastTailNode.sibling); + null === lastTailNode$40 + ? hasRenderedATailFallback || null === renderState.tail + ? (renderState.tail = null) + : (renderState.tail.sibling = null) + : (lastTailNode$40.sibling = null); + } } -function updateMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - if (null === current) { - var type = Component.type; - if ( - "function" === typeof type && - !shouldConstruct(type) && - void 0 === type.defaultProps && - null === Component.compare && - void 0 === Component.defaultProps +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + if (0 !== (completedWork.mode & 2)) { + for ( + var treeBaseDuration$42 = completedWork.selfBaseDuration, + child$43 = completedWork.child; + null !== child$43; + + ) + (newChildLanes |= child$43.lanes | child$43.childLanes), + (subtreeFlags |= child$43.subtreeFlags & 1835008), + (subtreeFlags |= child$43.flags & 1835008), + (treeBaseDuration$42 += child$43.treeBaseDuration), + (child$43 = child$43.sibling); + completedWork.treeBaseDuration = treeBaseDuration$42; + } else + for ( + treeBaseDuration$42 = completedWork.child; + null !== treeBaseDuration$42; + + ) + (newChildLanes |= + treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes), + (subtreeFlags |= treeBaseDuration$42.subtreeFlags & 1835008), + (subtreeFlags |= treeBaseDuration$42.flags & 1835008), + (treeBaseDuration$42.return = completedWork), + (treeBaseDuration$42 = treeBaseDuration$42.sibling); + else if (0 !== (completedWork.mode & 2)) { + treeBaseDuration$42 = completedWork.actualDuration; + child$43 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$42 += child.actualDuration), + (child$43 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$42; + completedWork.treeBaseDuration = child$43; + } else + for ( + treeBaseDuration$42 = completedWork.child; + null !== treeBaseDuration$42; + ) + (newChildLanes |= + treeBaseDuration$42.lanes | treeBaseDuration$42.childLanes), + (subtreeFlags |= treeBaseDuration$42.subtreeFlags), + (subtreeFlags |= treeBaseDuration$42.flags), + (treeBaseDuration$42.return = completedWork), + (treeBaseDuration$42 = treeBaseDuration$42.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case 2: + case 16: + case 15: + case 0: + case 11: + case 7: + case 8: + case 12: + case 9: + case 14: + return bubbleProperties(workInProgress), null; + case 1: return ( - (workInProgress.tag = 15), - (workInProgress.type = type), - updateSimpleMemoComponent( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 3: + return ( + (newProps = workInProgress.stateNode), + popHostContainer(), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + resetWorkInProgressVersions(), + newProps.pendingContext && + ((newProps.context = newProps.pendingContext), + (newProps.pendingContext = null)), + (null !== current && null !== current.child) || + newProps.hydrate || + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 5: + popHostContext(workInProgress); + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; + if (null !== current && null != workInProgress.stateNode) + updateHostComponent( current, workInProgress, type, - nextProps, - updateLanes, + newProps, renderLanes - ) - ); - current = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); - } - type = current.child; - if ( - 0 === (updateLanes & renderLanes) && - ((updateLanes = type.memoizedProps), - (Component = Component.compare), - (Component = null !== Component ? Component : shallowEqual), - Component(updateLanes, nextProps) && current.ref === workInProgress.ref) - ) - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - workInProgress.flags |= 1; - current = createWorkInProgress(type, nextProps); - current.ref = workInProgress.ref; - current.return = workInProgress; - return (workInProgress.child = current); -} -function updateSimpleMemoComponent( - current, - workInProgress, - Component, - nextProps, - updateLanes, - renderLanes -) { - if ( - null !== current && - shallowEqual(current.memoizedProps, nextProps) && - current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) - return ( - (workInProgress.lanes = current.lanes), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); -} -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - nextChildren = nextProps.children, - prevState = null !== current ? current.memoizedState : null; - if ( - "hidden" === nextProps.mode || - "unstable-defer-without-hiding" === nextProps.mode - ) - if (0 === (workInProgress.mode & 1)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= renderLanes); - else { - if (0 === (renderLanes & 1073741824)) - return ( - (current = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { - baseLanes: current, - cachePool: null - }), - (workInProgress.updateQueue = null), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= current), - null - ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); + ), + current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + else { + if (!newProps) { + if (null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + bubbleProperties(workInProgress); + return null; + } + requiredContext(contextStackCursor$1.current); + current = allocateTag(); + type = getViewConfigForType(type); + var updatePayload = diffProperties( + null, + emptyObject, + newProps, + type.validAttributes + ); + ReactNativePrivateInterface.UIManager.createView( + current, + type.uiViewClassName, + renderLanes, + updatePayload + ); + renderLanes = new ReactNativeFiberHostComponent( + current, + type, + workInProgress + ); + instanceCache.set(current, workInProgress); + instanceProps.set(current, newProps); + appendAllChildren(renderLanes, workInProgress, !1, !1); + workInProgress.stateNode = renderLanes; + finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 256); + } + bubbleProperties(workInProgress); + return null; + case 6: + if (current && null != workInProgress.stateNode) + updateHostText( + current, + workInProgress, + current.memoizedProps, + newProps + ); + else { + if ("string" !== typeof newProps && null === workInProgress.stateNode) + throw Error( + "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." + ); + current = requiredContext(rootInstanceStackCursor.current); + if (!requiredContext(contextStackCursor$1.current).isInAParentText) + throw Error( + "Text strings must be rendered within a component." + ); + renderLanes = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + renderLanes, + "RCTRawText", + current, + { text: newProps } + ); + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; + } + bubbleProperties(workInProgress); + return null; + case 13: + pop(suspenseStackCursor); + newProps = workInProgress.memoizedState; + if (0 !== (workInProgress.flags & 128)) + return ( + (workInProgress.lanes = renderLanes), + 0 !== (workInProgress.mode & 2) && + transferActualDuration(workInProgress), + workInProgress + ); + newProps = null !== newProps; + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if ( + newProps && + !renderLanes && + ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) + ) + if ( + (null === current && + !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || + 0 !== (suspenseStackCursor.current & 1) + ) + 0 === workInProgressRootExitStatus && + (workInProgressRootExitStatus = 3); + else { + if ( + 0 === workInProgressRootExitStatus || + 3 === workInProgressRootExitStatus + ) + workInProgressRootExitStatus = 4; + null === workInProgressRoot || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || + markRootSuspended$1( + workInProgressRoot, + workInProgressRootRenderLanes + ); + } + null !== workInProgress.updateQueue && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 2) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + return null; + case 4: + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); + case 10: + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); + case 17: + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); + case 19: + pop(suspenseStackCursor); + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; + if (null === updatePayload) + if (newProps) cutOffTailIfNeeded(type, !1); + else { + if ( + 0 !== workInProgressRootExitStatus || + (null !== current && 0 !== (current.flags & 128)) + ) + for (current = workInProgress.child; null !== current; ) { + updatePayload = findFirstSuspended(current); + if (null !== updatePayload) { + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); + current = updatePayload.updateQueue; + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)); + workInProgress.subtreeFlags = 0; + current = renderLanes; + for (newProps = workInProgress.child; null !== newProps; ) + (renderLanes = newProps), + (updatePayload = current), + (renderLanes.flags &= 1835010), + (type = renderLanes.alternate), + null === type + ? ((renderLanes.childLanes = 0), + (renderLanes.lanes = updatePayload), + (renderLanes.child = null), + (renderLanes.subtreeFlags = 0), + (renderLanes.memoizedProps = null), + (renderLanes.memoizedState = null), + (renderLanes.updateQueue = null), + (renderLanes.dependencies = null), + (renderLanes.stateNode = null), + (renderLanes.selfBaseDuration = 0), + (renderLanes.treeBaseDuration = 0)) + : ((renderLanes.childLanes = type.childLanes), + (renderLanes.lanes = type.lanes), + (renderLanes.child = type.child), + (renderLanes.subtreeFlags = 0), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = type.memoizedProps), + (renderLanes.memoizedState = type.memoizedState), + (renderLanes.updateQueue = type.updateQueue), + (renderLanes.type = type.type), + (updatePayload = type.dependencies), + (renderLanes.dependencies = + null === updatePayload + ? null + : { + lanes: updatePayload.lanes, + firstContext: updatePayload.firstContext + }), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), + (newProps = newProps.sibling); + push( + suspenseStackCursor, + (suspenseStackCursor.current & 1) | 2 + ); + return workInProgress.child; + } + current = current.sibling; + } + null !== type.tail && + now() > workInProgressRootRenderTargetTime && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + } + else { + if (!newProps) + if ( + ((current = findFirstSuspended(updatePayload)), null !== current) + ) { + if ( + ((workInProgress.flags |= 128), + (newProps = !0), + (current = current.updateQueue), + null !== current && + ((workInProgress.updateQueue = current), + (workInProgress.flags |= 4)), + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && + !updatePayload.alternate) + ) + return bubbleProperties(workInProgress), null; + } else + 2 * now() - type.renderingStartTime > + workInProgressRootRenderTargetTime && + 1073741824 !== renderLanes && + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 4194304)); + type.isBackwards + ? ((updatePayload.sibling = workInProgress.child), + (workInProgress.child = updatePayload)) + : ((current = type.last), + null !== current + ? (current.sibling = updatePayload) + : (workInProgress.child = updatePayload), + (type.last = updatePayload)); + } + if (null !== type.tail) + return ( + (workInProgress = type.tail), + (type.rendering = workInProgress), + (type.tail = workInProgress.sibling), + (type.renderingStartTime = now()), + (workInProgress.sibling = null), + (current = suspenseStackCursor.current), + push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), + workInProgress + ); + bubbleProperties(workInProgress); + return null; + case 22: + case 23: + return ( + popRenderLanes(), + (renderLanes = null !== workInProgress.memoizedState), + null !== current && + (null !== current.memoizedState) !== renderLanes && + "unstable-defer-without-hiding" !== newProps.mode && + 23 !== workInProgress.tag && + (workInProgress.flags |= 4096), + renderLanes && 0 !== (workInProgress.mode & 1) + ? 0 !== (subtreeRenderLanes & 1073741824) && + (bubbleProperties(workInProgress), + 23 !== workInProgress.tag && + workInProgress.subtreeFlags & 6 && + "unstable-defer-without-hiding" !== newProps.mode && + (workInProgress.flags |= 4096)) + : bubbleProperties(workInProgress), + null + ); + } + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); +} +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner, + didReceiveUpdate = !1; +function reconcileChildren(current, workInProgress, nextChildren, renderLanes) { + workInProgress.child = + null === current + ? mountChildFibers(workInProgress, null, nextChildren, renderLanes) + : reconcileChildFibers( + workInProgress, + current.child, + nextChildren, + renderLanes + ); +} +function updateForwardRef( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + Component = Component.render; + var ref = workInProgress.ref; + prepareToReadContext(workInProgress, renderLanes); + nextProps = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + ref, + renderLanes + ); + if (null !== current && !didReceiveUpdate) + return ( + (workInProgress.updateQueue = current.updateQueue), + (workInProgress.flags &= -1029), + (current.lanes &= ~renderLanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + workInProgress.flags |= 1; + reconcileChildren(current, workInProgress, nextProps, renderLanes); + return workInProgress.child; +} +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if (null === current) { + var type = Component.type; + if ( + "function" === typeof type && + !shouldConstruct(type) && + void 0 === type.defaultProps && + null === Component.compare && + void 0 === Component.defaultProps + ) + return ( + (workInProgress.tag = 15), + (workInProgress.type = type), + updateSimpleMemoComponent( + current, + workInProgress, + type, + nextProps, + renderLanes + ) + ); + current = createFiberFromTypeAndProps( + Component.type, + null, + nextProps, + workInProgress, + workInProgress.mode, + renderLanes + ); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); + } + type = current.child; + if (0 === (current.lanes & renderLanes)) { + var prevProps = type.memoizedProps; + Component = Component.compare; + Component = null !== Component ? Component : shallowEqual; + if (Component(prevProps, nextProps) && current.ref === workInProgress.ref) + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + workInProgress.flags |= 1; + current = createWorkInProgress(type, nextProps); + current.ref = workInProgress.ref; + current.return = workInProgress; + return (workInProgress.child = current); +} +function updateSimpleMemoComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes +) { + if ( + null !== current && + shallowEqual(current.memoizedProps, nextProps) && + current.ref === workInProgress.ref + ) + if (((didReceiveUpdate = !1), 0 !== (current.lanes & renderLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else + return ( + (workInProgress.lanes = current.lanes), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); +} +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps, + nextChildren = nextProps.children, + prevState = null !== current ? current.memoizedState : null; + if ( + "hidden" === nextProps.mode || + "unstable-defer-without-hiding" === nextProps.mode + ) + if (0 === (workInProgress.mode & 1)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null + ); + workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; + nextProps = null !== prevState ? prevState.baseLanes : renderLanes; + push(subtreeRenderLanesCursor, subtreeRenderLanes); subtreeRenderLanes |= nextProps; } else @@ -4355,7 +4797,7 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { +function markRef$1(current, workInProgress) { var ref = workInProgress.ref; if ( (null === current && null !== ref) || @@ -4591,876 +5033,500 @@ function updateClassComponent( current, workInProgress, Component, - nextProps, - hasContext, - renderLanes - ); -} -function finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes -) { - markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 128); - if (!shouldUpdate && !didCaptureError) - return ( - hasContext && invalidateContextProvider(workInProgress, Component, !1), - bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) - ); - shouldUpdate = workInProgress.stateNode; - ReactCurrentOwner$1.current = workInProgress; - if ( - didCaptureError && - "function" !== typeof Component.getDerivedStateFromError - ) { - var nextChildren = null; - profilerStartTime = -1; - } else nextChildren = shouldUpdate.render(); - workInProgress.flags |= 1; - null !== current && didCaptureError - ? ((didCaptureError = nextChildren), - (workInProgress.child = reconcileChildFibers( - workInProgress, - current.child, - null, - renderLanes - )), - (workInProgress.child = reconcileChildFibers( - workInProgress, - null, - didCaptureError, - renderLanes - ))) - : reconcileChildren(current, workInProgress, nextChildren, renderLanes); - workInProgress.memoizedState = shouldUpdate.state; - hasContext && invalidateContextProvider(workInProgress, Component, !0); - return workInProgress.child; -} -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - root.pendingContext - ? pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ) - : root.context && - pushTopLevelContextObject(workInProgress, root.context, !1); - pushHostContainer(workInProgress, root.containerInfo); -} -var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; -function mountSuspenseOffscreenState(renderLanes) { - return { baseLanes: renderLanes, cachePool: null }; -} -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps, - suspenseContext = suspenseStackCursor.current, - showFallback = !1, - JSCompiler_temp; - (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || - (JSCompiler_temp = - null !== current && null === current.memoizedState - ? !1 - : 0 !== (suspenseContext & 2)); - JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -129)) - : (null !== current && null === current.memoizedState) || - !0 === nextProps.unstable_avoidThisFallback || - (suspenseContext |= 1); - push(suspenseStackCursor, suspenseContext & 1); - if (null === current) { - current = nextProps.children; - suspenseContext = nextProps.fallback; - if (showFallback) - return ( - (current = mountSuspenseFallbackChildren( - workInProgress, - current, - suspenseContext, - renderLanes - )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - current - ); - if ("number" === typeof nextProps.unstable_expectedLoadTime) - return ( - (current = mountSuspenseFallbackChildren( - workInProgress, - current, - suspenseContext, - renderLanes - )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), - (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 4194304), - current - ); - renderLanes = createFiberFromOffscreen( - { mode: "visible", children: current }, - workInProgress.mode, - renderLanes, - null - ); - renderLanes.return = workInProgress; - return (workInProgress.child = renderLanes); - } - if (null !== current.memoizedState) { - if (showFallback) - return ( - (nextProps = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (showFallback = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (showFallback.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (showFallback.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; - } - if (showFallback) - return ( - (nextProps = updateSuspenseFallbackChildren( - current, - workInProgress, - nextProps.children, - nextProps.fallback, - renderLanes - )), - (showFallback = workInProgress.child), - (suspenseContext = current.child.memoizedState), - (showFallback.memoizedState = - null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), - (showFallback.childLanes = current.childLanes & ~renderLanes), - (workInProgress.memoizedState = SUSPENDED_MARKER), - nextProps - ); - renderLanes = updateSuspensePrimaryChildren( - current, - workInProgress, - nextProps.children, - renderLanes - ); - workInProgress.memoizedState = null; - return renderLanes; -} -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode, - progressedPrimaryFragment = workInProgress.child; - primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && null !== progressedPrimaryFragment - ? ((progressedPrimaryFragment.childLanes = 0), - (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 2 && - ((progressedPrimaryFragment.actualDuration = 0), - (progressedPrimaryFragment.actualStartTime = -1), - (progressedPrimaryFragment.selfBaseDuration = 0), - (progressedPrimaryFragment.treeBaseDuration = 0))) - : (progressedPrimaryFragment = createFiberFromOffscreen( - primaryChildren, - mode, - 0, - null - )); - fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); - progressedPrimaryFragment.return = workInProgress; - fallbackChildren.return = workInProgress; - progressedPrimaryFragment.sibling = fallbackChildren; - workInProgress.child = progressedPrimaryFragment; - return fallbackChildren; -} -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { - mode: "visible", - children: primaryChildren - }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); - primaryChildren.return = workInProgress; - primaryChildren.sibling = null; - null !== current && - ((renderLanes = workInProgress.deletions), - null === renderLanes - ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) - : renderLanes.push(current)); - return (workInProgress.child = primaryChildren); + nextProps, + hasContext, + renderLanes + ); } -function updateSuspenseFallbackChildren( +function finishClassComponent( current, workInProgress, - primaryChildren, - fallbackChildren, + Component, + shouldUpdate, + hasContext, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current - ? ((primaryChildren = workInProgress.child), - (primaryChildren.childLanes = 0), - (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 2 && - ((primaryChildren.actualDuration = 0), - (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = current.selfBaseDuration), - (primaryChildren.treeBaseDuration = current.treeBaseDuration)), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) - : ((fallbackChildren = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + markRef$1(current, workInProgress); + var didCaptureError = 0 !== (workInProgress.flags & 128); + if (!shouldUpdate && !didCaptureError) + return ( + hasContext && invalidateContextProvider(workInProgress, Component, !1), + bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) + ); + shouldUpdate = workInProgress.stateNode; + ReactCurrentOwner$1.current = workInProgress; + if ( + didCaptureError && + "function" !== typeof Component.getDerivedStateFromError + ) { + var nextChildren = null; + profilerStartTime = -1; + } else nextChildren = shouldUpdate.render(); + workInProgress.flags |= 1; + null !== current && didCaptureError + ? ((didCaptureError = nextChildren), + (workInProgress.child = reconcileChildFibers( + workInProgress, + current.child, + null, + renderLanes )), - (fallbackChildren.flags |= 2)); - fallbackChildren.return = workInProgress; - primaryChildren.return = workInProgress; - primaryChildren.sibling = fallbackChildren; - workInProgress.child = primaryChildren; - return fallbackChildren; + (workInProgress.child = reconcileChildFibers( + workInProgress, + null, + didCaptureError, + renderLanes + ))) + : reconcileChildren(current, workInProgress, nextChildren, renderLanes); + workInProgress.memoizedState = shouldUpdate.state; + hasContext && invalidateContextProvider(workInProgress, Component, !0); + return workInProgress.child; } -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes |= renderLanes; - var alternate = fiber.alternate; - null !== alternate && (alternate.lanes |= renderLanes); - scheduleWorkOnParentPath(fiber.return, renderLanes); +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; + root.pendingContext + ? pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ) + : root.context && + pushTopLevelContextObject(workInProgress, root.context, !1); + pushHostContainer(workInProgress, root.containerInfo); } -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode -) { - var renderState = workInProgress.memoizedState; - null === renderState - ? (workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }) - : ((renderState.isBackwards = isBackwards), - (renderState.rendering = null), - (renderState.renderingStartTime = 0), - (renderState.last = lastContentRow), - (renderState.tail = tail), - (renderState.tailMode = tailMode)); +var SUSPENDED_MARKER = { dehydrated: null, retryLane: 0 }; +function mountSuspenseOffscreenState(renderLanes) { + return { baseLanes: renderLanes, cachePool: null }; } -function updateSuspenseListComponent(current, workInProgress, renderLanes) { +function updateSuspenseComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, - revealOrder = nextProps.revealOrder, - tailMode = nextProps.tail; - reconcileChildren(current, workInProgress, nextProps.children, renderLanes); - nextProps = suspenseStackCursor.current; - if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); - else { - if (null !== current && 0 !== (current.flags & 128)) - a: for (current = workInProgress.child; null !== current; ) { - if (13 === current.tag) - null !== current.memoizedState && - scheduleWorkOnFiber(current, renderLanes); - else if (19 === current.tag) scheduleWorkOnFiber(current, renderLanes); - else if (null !== current.child) { - current.child.return = current; - current = current.child; - continue; - } - if (current === workInProgress) break a; - for (; null === current.sibling; ) { - if (null === current.return || current.return === workInProgress) - break a; - current = current.return; - } - current.sibling.return = current.return; - current = current.sibling; - } - nextProps &= 1; - } - push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; - else - switch (revealOrder) { - case "forwards": - renderLanes = workInProgress.child; - for (revealOrder = null; null !== renderLanes; ) - (current = renderLanes.alternate), - null !== current && - null === findFirstSuspended(current) && - (revealOrder = renderLanes), - (renderLanes = renderLanes.sibling); - renderLanes = revealOrder; - null === renderLanes - ? ((revealOrder = workInProgress.child), - (workInProgress.child = null)) - : ((revealOrder = renderLanes.sibling), (renderLanes.sibling = null)); - initSuspenseListRenderState( + suspenseContext = suspenseStackCursor.current, + showFallback = !1, + JSCompiler_temp; + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || + (JSCompiler_temp = + null !== current && null === current.memoizedState + ? !1 + : 0 !== (suspenseContext & 2)); + JSCompiler_temp + ? ((showFallback = !0), (workInProgress.flags &= -129)) + : (null !== current && null === current.memoizedState) || + !0 === nextProps.unstable_avoidThisFallback || + (suspenseContext |= 1); + push(suspenseStackCursor, suspenseContext & 1); + if (null === current) { + current = nextProps.children; + suspenseContext = nextProps.fallback; + if (showFallback) + return ( + (current = mountSuspenseFallbackChildren( workInProgress, - !1, - revealOrder, - renderLanes, - tailMode - ); - break; - case "backwards": - renderLanes = null; - revealOrder = workInProgress.child; - for (workInProgress.child = null; null !== revealOrder; ) { - current = revealOrder.alternate; - if (null !== current && null === findFirstSuspended(current)) { - workInProgress.child = revealOrder; - break; - } - current = revealOrder.sibling; - revealOrder.sibling = renderLanes; - renderLanes = revealOrder; - revealOrder = current; - } - initSuspenseListRenderState( + current, + suspenseContext, + renderLanes + )), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), + (workInProgress.memoizedState = SUSPENDED_MARKER), + current + ); + if ("number" === typeof nextProps.unstable_expectedLoadTime) + return ( + (current = mountSuspenseFallbackChildren( workInProgress, - !0, - renderLanes, - null, - tailMode - ); - break; - case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); - break; - default: - workInProgress.memoizedState = null; - } - return workInProgress.child; -} -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - null !== current && (workInProgress.dependencies = current.dependencies); - profilerStartTime = -1; - workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 === (renderLanes & workInProgress.childLanes)) return null; - if (null !== current && workInProgress.child !== current.child) - throw Error("Resuming work not yet implemented."); - if (null !== workInProgress.child) { - current = workInProgress.child; - renderLanes = createWorkInProgress(current, current.pendingProps); - workInProgress.child = renderLanes; - for (renderLanes.return = workInProgress; null !== current.sibling; ) - (current = current.sibling), - (renderLanes = renderLanes.sibling = createWorkInProgress( current, - current.pendingProps + suspenseContext, + renderLanes + )), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), + (workInProgress.memoizedState = SUSPENDED_MARKER), + (workInProgress.lanes = 4194304), + current + ); + renderLanes = createFiberFromOffscreen( + { mode: "visible", children: current }, + workInProgress.mode, + 0, + null + ); + renderLanes.return = workInProgress; + return (workInProgress.child = renderLanes); + } + if (null !== current.memoizedState) { + if (showFallback) + return ( + (nextProps = updateSuspenseFallbackChildren( + current, + workInProgress, + nextProps.children, + nextProps.fallback, + renderLanes )), - (renderLanes.return = workInProgress); - renderLanes.sibling = null; + (showFallback = workInProgress.child), + (suspenseContext = current.child.memoizedState), + (showFallback.memoizedState = + null === suspenseContext + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), + (showFallback.childLanes = current.childLanes & ~renderLanes), + (workInProgress.memoizedState = SUSPENDED_MARKER), + nextProps + ); + renderLanes = updateSuspensePrimaryChildren( + current, + workInProgress, + nextProps.children, + renderLanes + ); + workInProgress.memoizedState = null; + return renderLanes; } - return workInProgress.child; + if (showFallback) + return ( + (nextProps = updateSuspenseFallbackChildren( + current, + workInProgress, + nextProps.children, + nextProps.fallback, + renderLanes + )), + (showFallback = workInProgress.child), + (suspenseContext = current.child.memoizedState), + (showFallback.memoizedState = + null === suspenseContext + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), + (showFallback.childLanes = current.childLanes & ~renderLanes), + (workInProgress.memoizedState = SUSPENDED_MARKER), + nextProps + ); + renderLanes = updateSuspensePrimaryChildren( + current, + workInProgress, + nextProps.children, + renderLanes + ); + workInProgress.memoizedState = null; + return renderLanes; } -var appendAllChildren, - updateHostContainer, - updateHostComponent$1, - updateHostText$1; -appendAllChildren = function(parent, workInProgress) { - for (var node = workInProgress.child; null !== node; ) { - if (5 === node.tag || 6 === node.tag) parent._children.push(node.stateNode); - else if (4 !== node.tag && null !== node.child) { - node.child.return = node; - node = node.child; - continue; - } - if (node === workInProgress) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === workInProgress) return; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } -}; -updateHostContainer = function() {}; -updateHostComponent$1 = function(current, workInProgress, type, newProps) { - current.memoizedProps !== newProps && - (requiredContext(contextStackCursor$1.current), - (workInProgress.updateQueue = UPDATE_SIGNAL)) && - (workInProgress.flags |= 4); -}; -updateHostText$1 = function(current, workInProgress, oldText, newText) { - oldText !== newText && (workInProgress.flags |= 4); -}; -function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { - switch (renderState.tailMode) { - case "hidden": - hasRenderedATailFallback = renderState.tail; - for (var lastTailNode = null; null !== hasRenderedATailFallback; ) - null !== hasRenderedATailFallback.alternate && - (lastTailNode = hasRenderedATailFallback), - (hasRenderedATailFallback = hasRenderedATailFallback.sibling); - null === lastTailNode - ? (renderState.tail = null) - : (lastTailNode.sibling = null); - break; - case "collapsed": - lastTailNode = renderState.tail; - for (var lastTailNode$72 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$72 = lastTailNode), - (lastTailNode = lastTailNode.sibling); - null === lastTailNode$72 - ? hasRenderedATailFallback || null === renderState.tail - ? (renderState.tail = null) - : (renderState.tail.sibling = null) - : (lastTailNode$72.sibling = null); - } +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode, + progressedPrimaryFragment = workInProgress.child; + primaryChildren = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && null !== progressedPrimaryFragment + ? ((progressedPrimaryFragment.childLanes = 0), + (progressedPrimaryFragment.pendingProps = primaryChildren), + workInProgress.mode & 2 && + ((progressedPrimaryFragment.actualDuration = 0), + (progressedPrimaryFragment.actualStartTime = -1), + (progressedPrimaryFragment.selfBaseDuration = 0), + (progressedPrimaryFragment.treeBaseDuration = 0))) + : (progressedPrimaryFragment = createFiberFromOffscreen( + primaryChildren, + mode, + 0, + null + )); + fallbackChildren = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + progressedPrimaryFragment.return = workInProgress; + fallbackChildren.return = workInProgress; + progressedPrimaryFragment.sibling = fallbackChildren; + workInProgress.child = progressedPrimaryFragment; + return fallbackChildren; } -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - if (0 !== (completedWork.mode & 2)) { - for ( - var treeBaseDuration$74 = completedWork.selfBaseDuration, - child$75 = completedWork.child; - null !== child$75; - - ) - (newChildLanes |= child$75.lanes | child$75.childLanes), - (subtreeFlags |= child$75.subtreeFlags & 1835008), - (subtreeFlags |= child$75.flags & 1835008), - (treeBaseDuration$74 += child$75.treeBaseDuration), - (child$75 = child$75.sibling); - completedWork.treeBaseDuration = treeBaseDuration$74; - } else - for ( - treeBaseDuration$74 = completedWork.child; - null !== treeBaseDuration$74; - - ) - (newChildLanes |= - treeBaseDuration$74.lanes | treeBaseDuration$74.childLanes), - (subtreeFlags |= treeBaseDuration$74.subtreeFlags & 1835008), - (subtreeFlags |= treeBaseDuration$74.flags & 1835008), - (treeBaseDuration$74.return = completedWork), - (treeBaseDuration$74 = treeBaseDuration$74.sibling); - else if (0 !== (completedWork.mode & 2)) { - treeBaseDuration$74 = completedWork.actualDuration; - child$75 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$74 += child.actualDuration), - (child$75 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$74; - completedWork.treeBaseDuration = child$75; - } else - for ( - treeBaseDuration$74 = completedWork.child; - null !== treeBaseDuration$74; - - ) - (newChildLanes |= - treeBaseDuration$74.lanes | treeBaseDuration$74.childLanes), - (subtreeFlags |= treeBaseDuration$74.subtreeFlags), - (subtreeFlags |= treeBaseDuration$74.flags), - (treeBaseDuration$74.return = completedWork), - (treeBaseDuration$74 = treeBaseDuration$74.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + current = currentPrimaryChildFragment.sibling; + primaryChildren = createWorkInProgress(currentPrimaryChildFragment, { + mode: "visible", + children: primaryChildren + }); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); + primaryChildren.return = workInProgress; + primaryChildren.sibling = null; + null !== current && + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); + return (workInProgress.child = primaryChildren); } -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; - switch (workInProgress.tag) { - case 2: - case 16: - case 15: - case 0: - case 11: - case 7: - case 8: - case 12: - case 9: - case 14: - return bubbleProperties(workInProgress), null; - case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); - case 3: - return ( - (newProps = workInProgress.stateNode), - popHostContainer(), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - resetWorkInProgressVersions(), - newProps.pendingContext && - ((newProps.context = newProps.pendingContext), - (newProps.pendingContext = null)), - (null !== current && null !== current.child) || - newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), +function updateSuspenseFallbackChildren( + current, + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + current = current.child; + var currentFallbackChildFragment = current.sibling, + primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 1) && workInProgress.child !== current + ? ((primaryChildren = workInProgress.child), + (primaryChildren.childLanes = 0), + (primaryChildren.pendingProps = primaryChildProps), + workInProgress.mode & 2 && + ((primaryChildren.actualDuration = 0), + (primaryChildren.actualStartTime = -1), + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 1835008)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) + : ((fallbackChildren = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, null - ); - case 5: - popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; - if (null !== current && null != workInProgress.stateNode) - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - renderLanes - ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); - else { - if (!newProps) { - if (null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - bubbleProperties(workInProgress); - return null; + )), + (fallbackChildren.flags |= 2)); + fallbackChildren.return = workInProgress; + primaryChildren.return = workInProgress; + primaryChildren.sibling = fallbackChildren; + workInProgress.child = primaryChildren; + return fallbackChildren; +} +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes |= renderLanes; + var alternate = fiber.alternate; + null !== alternate && (alternate.lanes |= renderLanes); + scheduleWorkOnParentPath(fiber.return, renderLanes); +} +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; + null === renderState + ? (workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode + }) + : ((renderState.isBackwards = isBackwards), + (renderState.rendering = null), + (renderState.renderingStartTime = 0), + (renderState.last = lastContentRow), + (renderState.tail = tail), + (renderState.tailMode = tailMode)); +} +function updateSuspenseListComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps, + revealOrder = nextProps.revealOrder, + tailMode = nextProps.tail; + reconcileChildren(current, workInProgress, nextProps.children, renderLanes); + nextProps = suspenseStackCursor.current; + if (0 !== (nextProps & 2)) + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); + else { + if (null !== current && 0 !== (current.flags & 128)) + a: for (current = workInProgress.child; null !== current; ) { + if (13 === current.tag) + null !== current.memoizedState && + scheduleWorkOnFiber(current, renderLanes); + else if (19 === current.tag) scheduleWorkOnFiber(current, renderLanes); + else if (null !== current.child) { + current.child.return = current; + current = current.child; + continue; } - requiredContext(contextStackCursor$1.current); - current = allocateTag(); - type = getViewConfigForType(type); - var updatePayload = diffProperties( - null, - emptyObject, - newProps, - type.validAttributes - ); - ReactNativePrivateInterface.UIManager.createView( - current, - type.uiViewClassName, - renderLanes, - updatePayload - ); - renderLanes = new ReactNativeFiberHostComponent( - current, - type, - workInProgress - ); - instanceCache.set(current, workInProgress); - instanceProps.set(current, newProps); - appendAllChildren(renderLanes, workInProgress, !1, !1); - workInProgress.stateNode = renderLanes; - finalizeInitialChildren(renderLanes) && (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 256); + if (current === workInProgress) break a; + for (; null === current.sibling; ) { + if (null === current.return || current.return === workInProgress) + break a; + current = current.return; + } + current.sibling.return = current.return; + current = current.sibling; } - bubbleProperties(workInProgress); - return null; - case 6: - if (current && null != workInProgress.stateNode) - updateHostText$1( - current, + nextProps &= 1; + } + push(suspenseStackCursor, nextProps); + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; + else + switch (revealOrder) { + case "forwards": + renderLanes = workInProgress.child; + for (revealOrder = null; null !== renderLanes; ) + (current = renderLanes.alternate), + null !== current && + null === findFirstSuspended(current) && + (revealOrder = renderLanes), + (renderLanes = renderLanes.sibling); + renderLanes = revealOrder; + null === renderLanes + ? ((revealOrder = workInProgress.child), + (workInProgress.child = null)) + : ((revealOrder = renderLanes.sibling), (renderLanes.sibling = null)); + initSuspenseListRenderState( workInProgress, - current.memoizedProps, - newProps - ); - else { - if ("string" !== typeof newProps && null === workInProgress.stateNode) - throw Error( - "We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue." - ); - current = requiredContext(rootInstanceStackCursor.current); - if (!requiredContext(contextStackCursor$1.current).isInAParentText) - throw Error( - "Text strings must be rendered within a component." - ); - renderLanes = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( + !1, + revealOrder, renderLanes, - "RCTRawText", - current, - { text: newProps } - ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; - } - bubbleProperties(workInProgress); - return null; - case 13: - pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) - return ( - (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 2) && - transferActualDuration(workInProgress), - workInProgress + tailMode ); - newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if ( - newProps && - !renderLanes && - ((workInProgress.child.flags |= 4096), 0 !== (workInProgress.mode & 1)) - ) - if ( - (null === current && - !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || - 0 !== (suspenseStackCursor.current & 1) - ) - 0 === workInProgressRootExitStatus && - (workInProgressRootExitStatus = 3); - else { - if ( - 0 === workInProgressRootExitStatus || - 3 === workInProgressRootExitStatus - ) - workInProgressRootExitStatus = 4; - null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || - markRootSuspended$1( - workInProgressRoot, - workInProgressRootRenderLanes - ); + break; + case "backwards": + renderLanes = null; + revealOrder = workInProgress.child; + for (workInProgress.child = null; null !== revealOrder; ) { + current = revealOrder.alternate; + if (null !== current && null === findFirstSuspended(current)) { + workInProgress.child = revealOrder; + break; + } + current = revealOrder.sibling; + revealOrder.sibling = renderLanes; + renderLanes = revealOrder; + revealOrder = current; } - null !== workInProgress.updateQueue && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 2) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); - return null; + initSuspenseListRenderState( + workInProgress, + !0, + renderLanes, + null, + tailMode + ); + break; + case "together": + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + break; + default: + workInProgress.memoizedState = null; + } + return workInProgress.child; +} +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + null !== current && (workInProgress.dependencies = current.dependencies); + profilerStartTime = -1; + workInProgressRootSkippedLanes |= workInProgress.lanes; + if (0 === (renderLanes & workInProgress.childLanes)) return null; + if (null !== current && workInProgress.child !== current.child) + throw Error("Resuming work not yet implemented."); + if (null !== workInProgress.child) { + current = workInProgress.child; + renderLanes = createWorkInProgress(current, current.pendingProps); + workInProgress.child = renderLanes; + for (renderLanes.return = workInProgress; null !== current.sibling; ) + (current = current.sibling), + (renderLanes = renderLanes.sibling = createWorkInProgress( + current, + current.pendingProps + )), + (renderLanes.return = workInProgress); + renderLanes.sibling = null; + } + return workInProgress.child; +} +function attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes +) { + switch (workInProgress.tag) { + case 3: + pushHostRootContext(workInProgress); + break; + case 5: + pushHostContext(workInProgress); + break; + case 1: + isContextProvider(workInProgress.type) && + pushContextProvider(workInProgress); + break; case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + break; case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); - case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + var context = workInProgress.type._context, + nextValue = workInProgress.memoizedProps.value; + push(valueCursor, context._currentValue); + context._currentValue = nextValue; + break; + case 12: + 0 !== (renderLanes & workInProgress.childLanes) && + (workInProgress.flags |= 4); + context = workInProgress.stateNode; + context.effectDuration = 0; + context.passiveEffectDuration = 0; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent(current, workInProgress, renderLanes); + push(suspenseStackCursor, suspenseStackCursor.current & 1); + current = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); + return null !== current ? current.sibling : null; + } + push(suspenseStackCursor, suspenseStackCursor.current & 1); + break; case 19: - pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; - if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); - else { - if ( - 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) - ) - for (current = workInProgress.child; null !== current; ) { - updatePayload = findFirstSuspended(current); - if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); - current = updatePayload.updateQueue; - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; - current = renderLanes; - for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (updatePayload = current), - (renderLanes.flags &= 1835010), - (type = renderLanes.alternate), - null === type - ? ((renderLanes.childLanes = 0), - (renderLanes.lanes = updatePayload), - (renderLanes.child = null), - (renderLanes.subtreeFlags = 0), - (renderLanes.memoizedProps = null), - (renderLanes.memoizedState = null), - (renderLanes.updateQueue = null), - (renderLanes.dependencies = null), - (renderLanes.stateNode = null), - (renderLanes.selfBaseDuration = 0), - (renderLanes.treeBaseDuration = 0)) - : ((renderLanes.childLanes = type.childLanes), - (renderLanes.lanes = type.lanes), - (renderLanes.child = type.child), - (renderLanes.subtreeFlags = 0), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = - null === updatePayload - ? null - : { - lanes: updatePayload.lanes, - firstContext: updatePayload.firstContext - }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), - (newProps = newProps.sibling); - push( - suspenseStackCursor, - (suspenseStackCursor.current & 1) | 2 - ); - return workInProgress.child; - } - current = current.sibling; - } - null !== type.tail && - now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - } - else { - if (!newProps) - if ( - ((current = findFirstSuspended(updatePayload)), null !== current) - ) { - if ( - ((workInProgress.flags |= 128), - (newProps = !0), - (current = current.updateQueue), - null !== current && - ((workInProgress.updateQueue = current), - (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && - !updatePayload.alternate) - ) - return bubbleProperties(workInProgress), null; - } else - 2 * now() - type.renderingStartTime > - workInProgressRootRenderTargetTime && - 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 4194304)); - type.isBackwards - ? ((updatePayload.sibling = workInProgress.child), - (workInProgress.child = updatePayload)) - : ((current = type.last), - null !== current - ? (current.sibling = updatePayload) - : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + context = 0 !== (renderLanes & workInProgress.childLanes); + if (0 !== (current.flags & 128)) { + if (context) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 128; } - if (null !== type.tail) - return ( - (workInProgress = type.tail), - (type.rendering = workInProgress), - (type.tail = workInProgress.sibling), - (type.renderingStartTime = now()), - (workInProgress.sibling = null), - (current = suspenseStackCursor.current), - push(suspenseStackCursor, newProps ? (current & 1) | 2 : current & 1), - workInProgress - ); - bubbleProperties(workInProgress); - return null; + nextValue = workInProgress.memoizedState; + null !== nextValue && + ((nextValue.rendering = null), + (nextValue.tail = null), + (nextValue.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (context) break; + else return null; case 22: case 23: return ( - popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), - null !== current && - (null !== current.memoizedState) !== renderLanes && - "unstable-defer-without-hiding" !== newProps.mode && - 23 !== workInProgress.tag && - (workInProgress.flags |= 4096), - renderLanes && 0 !== (workInProgress.mode & 1) - ? 0 !== (subtreeRenderLanes & 1073741824) && - (bubbleProperties(workInProgress), - 23 !== workInProgress.tag && - workInProgress.subtreeFlags & 6 && - "unstable-defer-without-hiding" !== newProps.mode && - (workInProgress.flags |= 4096)) - : bubbleProperties(workInProgress), - null + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) ); } - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } function unwindWork(workInProgress) { switch (workInProgress.tag) { @@ -5629,8 +5695,8 @@ function commitHookEffectListMount(tag, finishedWork) { var effect = (finishedWork = finishedWork.next); do { if ((effect.tag & tag) === tag) { - var create$88 = effect.create; - effect.destroy = create$88(); + var create$89 = effect.create; + effect.destroy = create$89(); } effect = effect.next; } while (effect !== finishedWork); @@ -6113,8 +6179,8 @@ function commitMutationEffects(root, firstChild, committedLanes) { switch (firstChild.tag) { case 13: if (null !== firstChild.memoizedState) { - var current$95 = firstChild.alternate; - if (null === current$95 || null === current$95.memoizedState) + var current$96 = firstChild.alternate; + if (null === current$96 || null === current$96.memoizedState) globalMostRecentFallbackTime = now(); } break; @@ -6298,21 +6364,21 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { commitUpdateQueue(committedLanes, updateQueue, instance); break; case 3: - var updateQueue$90 = committedLanes.updateQueue; - if (null !== updateQueue$90) { - var instance$91 = null; + var updateQueue$91 = committedLanes.updateQueue; + if (null !== updateQueue$91) { + var instance$92 = null; if (null !== committedLanes.child) switch (committedLanes.child.tag) { case 5: - instance$91 = committedLanes.child.stateNode; + instance$92 = committedLanes.child.stateNode; break; case 1: - instance$91 = committedLanes.child.stateNode; + instance$92 = committedLanes.child.stateNode; } commitUpdateQueue( committedLanes, - updateQueue$90, - instance$91 + updateQueue$91, + instance$92 ); } break; @@ -6327,7 +6393,7 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { onCommit = _finishedWork$memoize2.onCommit, onRender = _finishedWork$memoize2.onRender, effectDuration = committedLanes.stateNode.effectDuration; - instance$91 = commitTime; + instance$92 = commitTime; current = null === current ? "mount" : "update"; currentUpdateIsNested && (current = "nested-update"); "function" === typeof onRender && @@ -6337,14 +6403,14 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { committedLanes.actualDuration, committedLanes.treeBaseDuration, committedLanes.actualStartTime, - instance$91 + instance$92 ); "function" === typeof onCommit && onCommit( committedLanes.memoizedProps.id, current, effectDuration, - instance$91 + instance$92 ); enqueuePendingPassiveProfilerEffect(committedLanes); var parentFiber = committedLanes.return; @@ -6374,27 +6440,27 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { ); } if (committedLanes.flags & 256) { - instance$91 = void 0; + instance$92 = void 0; current = committedLanes; var ref = current.ref; if (null !== ref) { var instance$jscomp$0 = current.stateNode; switch (current.tag) { case 5: - instance$91 = instance$jscomp$0; + instance$92 = instance$jscomp$0; break; default: - instance$91 = instance$jscomp$0; + instance$92 = instance$jscomp$0; } if ("function" === typeof ref) if (current.mode & 2) try { - startLayoutEffectTimer(), ref(instance$91); + startLayoutEffectTimer(), ref(instance$92); } finally { recordLayoutEffectDuration(current); } - else ref(instance$91); - else ref.current = instance$91; + else ref(instance$92); + else ref.current = instance$92; } } } catch (error) { @@ -6409,10 +6475,10 @@ function commitLayoutEffects(finishedWork, root, committedLanes) { nextEffect = null; break; } - instance$91 = committedLanes.sibling; - if (null !== instance$91) { - instance$91.return = committedLanes.return; - nextEffect = instance$91; + instance$92 = committedLanes.sibling; + if (null !== instance$92) { + instance$92.return = committedLanes.return; + nextEffect = instance$92; break; } nextEffect = committedLanes.return; @@ -7524,7 +7590,6 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { } var beginWork$1; beginWork$1 = function(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; if (null !== current) if ( current.memoizedProps !== workInProgress.pendingProps || @@ -7532,165 +7597,98 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ) didReceiveUpdate = !0; else { - if (0 === (renderLanes & updateLanes)) { - didReceiveUpdate = !1; - switch (workInProgress.tag) { - case 3: - pushHostRootContext(workInProgress); - break; - case 5: - pushHostContext(workInProgress); - break; - case 1: - isContextProvider(workInProgress.type) && - pushContextProvider(workInProgress); - break; - case 4: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; - case 10: - updateLanes = workInProgress.type._context; - var nextValue = workInProgress.memoizedProps.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = nextValue; - break; - case 12: - 0 !== (renderLanes & workInProgress.childLanes) && - (workInProgress.flags |= 4); - updateLanes = workInProgress.stateNode; - updateLanes.effectDuration = 0; - updateLanes.passiveEffectDuration = 0; - break; - case 13: - if (null !== workInProgress.memoizedState) { - if (0 !== (renderLanes & workInProgress.child.childLanes)) - return updateSuspenseComponent( - current, - workInProgress, - renderLanes - ); - push(suspenseStackCursor, suspenseStackCursor.current & 1); - workInProgress = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 128)) { - if (updateLanes) - return updateSuspenseListComponent( - current, - workInProgress, - renderLanes - ); - workInProgress.flags |= 128; - } - nextValue = workInProgress.memoizedState; - null !== nextValue && - ((nextValue.rendering = null), - (nextValue.tail = null), - (nextValue.lastEffect = null)); - push(suspenseStackCursor, suspenseStackCursor.current); - if (updateLanes) break; - else return null; - case 22: - case 23: - return ( - (workInProgress.lanes = 0), - updateOffscreenComponent(current, workInProgress, renderLanes) - ); - } - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes + if ( + 0 === (current.lanes & renderLanes) && + 0 === (workInProgress.flags & 128) + ) + return ( + (didReceiveUpdate = !1), + attemptEarlyBailoutIfNoScheduledUpdate( + current, + workInProgress, + renderLanes + ) ); - } didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; switch (workInProgress.tag) { case 2: - updateLanes = workInProgress.type; + var Component = workInProgress.type; null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + var context = getMaskedContext( + workInProgress, + contextStackCursor.current + ); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, - updateLanes, + Component, current, - nextValue, + context, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof nextValue && - null !== nextValue && - "function" === typeof nextValue.render && - void 0 === nextValue.$$typeof + "object" === typeof context && + null !== context && + "function" === typeof context.render && + void 0 === context.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; workInProgress.updateQueue = null; - if (isContextProvider(updateLanes)) { + if (isContextProvider(Component)) { var hasContext = !0; pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== nextValue.state && void 0 !== nextValue.state - ? nextValue.state + null !== context.state && void 0 !== context.state + ? context.state : null; initializeUpdateQueue(workInProgress); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; - mountClassInstance(workInProgress, updateLanes, current, renderLanes); + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; + mountClassInstance(workInProgress, Component, current, renderLanes); workInProgress = finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, hasContext, renderLanes ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, nextValue, renderLanes), + reconcileChildren(null, workInProgress, context, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - nextValue = workInProgress.elementType; + Component = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = nextValue._init; - nextValue = hasContext(nextValue._payload); - workInProgress.type = nextValue; - hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); - current = resolveDefaultProps(nextValue, current); - switch (hasContext) { + context = Component._init; + Component = context(Component._payload); + workInProgress.type = Component; + context = workInProgress.tag = resolveLazyComponentTag(Component); + current = resolveDefaultProps(Component, current); + switch (context) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7699,7 +7697,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7708,7 +7706,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + Component, current, renderLanes ); @@ -7717,79 +7715,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), - updateLanes, + Component, + resolveDefaultProps(Component.type, current), renderLanes ); break a; } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + Component + ". Lazy element type must resolve to a class or function." ); } return workInProgress; case 0: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateFunctionComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 1: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateClassComponent( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); case 3: pushHostRootContext(workInProgress); - updateLanes = workInProgress.updateQueue; - if (null === current || null === updateLanes) + Component = workInProgress.updateQueue; + if (null === current || null === Component) throw Error( "If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue." ); - nextValue = workInProgress.pendingProps; - updateLanes = workInProgress.memoizedState.element; + context = workInProgress.pendingProps; + Component = workInProgress.memoizedState.element; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, context, null, renderLanes); + context = workInProgress.memoizedState.element; + context === Component ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, context, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: return ( pushHostContext(workInProgress), - (updateLanes = workInProgress.pendingProps.children), - markRef(current, workInProgress), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + (Component = workInProgress.pendingProps.children), + markRef$1(current, workInProgress), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 6: @@ -7802,35 +7799,30 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.stateNode.containerInfo ), - (updateLanes = workInProgress.pendingProps), + (Component = workInProgress.pendingProps), null === current ? (workInProgress.child = reconcileChildFibers( workInProgress, null, - updateLanes, + Component, renderLanes )) - : reconcileChildren( - current, - workInProgress, - updateLanes, - renderLanes - ), + : reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 11: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), updateForwardRef( current, workInProgress, - updateLanes, - nextValue, + Component, + context, renderLanes ) ); @@ -7857,9 +7849,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 12: return ( (workInProgress.flags |= 4), - (updateLanes = workInProgress.stateNode), - (updateLanes.effectDuration = 0), - (updateLanes.passiveEffectDuration = 0), + (Component = workInProgress.stateNode), + (Component.effectDuration = 0), + (Component.passiveEffectDuration = 0), reconcileChildren( current, workInProgress, @@ -7870,16 +7862,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); case 10: a: { - updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + Component = workInProgress.type._context; + context = workInProgress.pendingProps; hasContext = workInProgress.memoizedProps; - var newValue = nextValue.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = newValue; + var newValue = context.value; + push(valueCursor, Component._currentValue); + Component._currentValue = newValue; if (null !== hasContext) if (objectIs(hasContext.value, newValue)) { if ( - hasContext.children === nextValue.children && + hasContext.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7904,7 +7896,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { null !== dependency; ) { - if (dependency.context === updateLanes) { + if (dependency.context === Component) { if (1 === newValue.tag) { dependency = createUpdate(-1, renderLanes & -renderLanes); dependency.tag = 2; @@ -7955,7 +7947,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7963,29 +7955,25 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), - (updateLanes = workInProgress.pendingProps.children), + (context = workInProgress.type), + (Component = workInProgress.pendingProps.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context)), + (Component = Component(context)), (workInProgress.flags |= 1), - reconcileChildren(current, workInProgress, updateLanes, renderLanes), + reconcileChildren(current, workInProgress, Component, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), - (hasContext = resolveDefaultProps( - nextValue, - workInProgress.pendingProps - )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (Component = workInProgress.type), + (context = resolveDefaultProps(Component, workInProgress.pendingProps)), + (context = resolveDefaultProps(Component.type, context)), updateMemoComponent( current, workInProgress, - nextValue, - hasContext, - updateLanes, + Component, + context, renderLanes ) ); @@ -7995,32 +7983,31 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress, workInProgress.type, workInProgress.pendingProps, - updateLanes, renderLanes ); case 17: return ( - (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = - workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + (Component = workInProgress.type), + (context = workInProgress.pendingProps), + (context = + workInProgress.elementType === Component + ? context + : resolveDefaultProps(Component, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)), (workInProgress.tag = 1), - isContextProvider(updateLanes) + isContextProvider(Component) ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, Component, context), + mountClassInstance(workInProgress, Component, context, renderLanes), finishClassComponent( null, workInProgress, - updateLanes, + Component, !0, current, renderLanes @@ -8467,10 +8454,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_1011 = { + devToolsConfig$jscomp$inline_1014 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "18.0.0-419cc9c37-20210726", + version: "18.0.0-19092ac8c-20210803", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8485,11 +8472,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1278 = { - bundleType: devToolsConfig$jscomp$inline_1011.bundleType, - version: devToolsConfig$jscomp$inline_1011.version, - rendererPackageName: devToolsConfig$jscomp$inline_1011.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_1011.rendererConfig, +var internals$jscomp$inline_1287 = { + bundleType: devToolsConfig$jscomp$inline_1014.bundleType, + version: devToolsConfig$jscomp$inline_1014.version, + rendererPackageName: devToolsConfig$jscomp$inline_1014.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_1014.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8505,26 +8492,26 @@ var internals$jscomp$inline_1278 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_1011.findFiberByHostInstance || + devToolsConfig$jscomp$inline_1014.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "18.0.0-419cc9c37-20210726" + reconcilerVersion: "18.0.0-19092ac8c-20210803" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1279 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1288 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1279.isDisabled && - hook$jscomp$inline_1279.supportsFiber + !hook$jscomp$inline_1288.isDisabled && + hook$jscomp$inline_1288.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1279.inject( - internals$jscomp$inline_1278 + (rendererID = hook$jscomp$inline_1288.inject( + internals$jscomp$inline_1287 )), - (injectedHook = hook$jscomp$inline_1279); + (injectedHook = hook$jscomp$inline_1288); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index e534a84a4e7479..3af1555124545f 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -6,7 +6,9 @@ * * @format * @flow - * @generated SignedSource<> + * @generated SignedSource<<40f01afd3b6d95a617ac8e48748a2a76>> + * + * This file was sync'd from the facebook/react repository. */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactFeatureFlags.js b/Libraries/Renderer/shims/ReactFeatureFlags.js index a58b5ff818891d..45ce2c7a94df55 100644 --- a/Libraries/Renderer/shims/ReactFeatureFlags.js +++ b/Libraries/Renderer/shims/ReactFeatureFlags.js @@ -6,7 +6,9 @@ * * @format * @flow strict-local - * @generated SignedSource<<7fc82101078b5f2226a6b58a9715ec95>> + * @generated SignedSource<> + * + * This file was sync'd from the facebook/react repository. */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactNative.js b/Libraries/Renderer/shims/ReactNative.js index 44b99aae98343d..f0c54b8d13b6a4 100644 --- a/Libraries/Renderer/shims/ReactNative.js +++ b/Libraries/Renderer/shims/ReactNative.js @@ -6,7 +6,9 @@ * * @format * @flow - * @generated SignedSource<<2d98809d55453ea61e203a8425692891>> + * @generated SignedSource<> + * + * This file was sync'd from the facebook/react repository. */ 'use strict'; diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index dfb03d6818361a..d0dcd60815ff59 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -6,7 +6,9 @@ * * @format * @flow strict - * @generated SignedSource<> + * @generated SignedSource<<67969011689de134487d7110b6519058>> + * + * This file was sync'd from the facebook/react repository. */ import type {ElementRef, ElementType, Element, AbstractComponent} from 'react'; diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index 80e5b2b923719f..b8e08eec174c0d 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -6,7 +6,9 @@ * * @format * @flow strict-local - * @generated SignedSource<<3276da8ef0bf14ad0623df6e1f704d72>> + * @generated SignedSource<<5b2da3e92f44ee2684113b45af052f5d>> + * + * This file was sync'd from the facebook/react repository. */ /* eslint-disable react-internal/invariant-args */ diff --git a/Libraries/Renderer/shims/createReactNativeComponentClass.js b/Libraries/Renderer/shims/createReactNativeComponentClass.js index 989eafba76043c..b4711953fe0735 100644 --- a/Libraries/Renderer/shims/createReactNativeComponentClass.js +++ b/Libraries/Renderer/shims/createReactNativeComponentClass.js @@ -6,7 +6,9 @@ * * @format * @flow strict-local - * @generated SignedSource<<745b7b5c173d0bc75b6d97938c98728d>> + * @generated SignedSource<<435ec24b3531c66986fe5d529795713b>> + * + * This file was sync'd from the facebook/react repository. */ 'use strict';