From 013b39f32ccc3e15ca4f3d2b87066e1424e9798c Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Wed, 24 Feb 2021 08:12:26 -0800 Subject: [PATCH 01/51] Fabric: Using `SurfaceHandler` on iOS Summary: (This is the second version of the diff that includes additional checkes and syncronization around `start` and `stop` methods). This diff migrates iOS renderer to using SurfaceHandler directly instead of calling Scheduler methods. Major changes: * RCTFabricSurface only stores a SurfaceHandler and platform-specific parts (such as a UIView instance and TouchHandler); all other pieces of state are stored in SurfaceHandler object. * All the state changes initiated from RCTFabricSurface are performed via calling corresponding methods on SurfaceHandler (bypassing RCTSurfacePresenter, RCTScheduler, Scheduler, and UIManager). * Every RCTSurfaceHandler is responsible for observing `UIContentSizeCategoryDidChangeNotification` and communicating the change down to SurfaceHandler. (Besides code simplifications it's more correct because on iOS the DPI actually depends on a particular UIScreen/UIWindow associated with UIView and *not* global for the whole app.) Changelog: [Internal] Fabric-specific internal change. Reviewed By: ShikaSD Differential Revision: D26614577 fbshipit-source-id: 428f4c4cc1ca46cd97be0413e9279e29a54807f6 --- React/Fabric/RCTScheduler.h | 20 +- React/Fabric/RCTScheduler.mm | 41 +--- React/Fabric/RCTSurfacePresenter.h | 24 +-- React/Fabric/RCTSurfacePresenter.mm | 141 ++----------- React/Fabric/Surface/RCTFabricSurface.h | 8 +- React/Fabric/Surface/RCTFabricSurface.mm | 256 +++++++++++------------ 6 files changed, 160 insertions(+), 330 deletions(-) diff --git a/React/Fabric/RCTScheduler.h b/React/Fabric/RCTScheduler.h index 55670daca64646..6eca003c03356b 100644 --- a/React/Fabric/RCTScheduler.h +++ b/React/Fabric/RCTScheduler.h @@ -14,6 +14,7 @@ #import #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -47,26 +48,13 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithToolbox:(facebook::react::SchedulerToolbox)toolbox; -- (void)startSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId - moduleName:(NSString *)moduleName - initialProps:(NSDictionary *)initialProps - layoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints - layoutContext:(facebook::react::LayoutContext)layoutContext; - -- (void)stopSurfaceWithSurfaceId:(facebook::react::SurfaceId)surfaceId; - -- (CGSize)measureSurfaceWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints - layoutContext:(facebook::react::LayoutContext)layoutContext - surfaceId:(facebook::react::SurfaceId)surfaceId; - -- (void)constraintSurfaceLayoutWithLayoutConstraints:(facebook::react::LayoutConstraints)layoutConstraints - layoutContext:(facebook::react::LayoutContext)layoutContext - surfaceId:(facebook::react::SurfaceId)surfaceId; +- (void)registerSurface:(facebook::react::SurfaceHandler const &)surfaceHandler; +- (void)unregisterSurface:(facebook::react::SurfaceHandler const &)surfaceHandler; - (facebook::react::ComponentDescriptor const *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN: (facebook::react::ComponentHandle)handle; -- (facebook::react::MountingCoordinator::Shared)mountingCoordinatorWithSurfaceId:(facebook::react::SurfaceId)surfaceId; +- (void)setupAnimationDriver:(facebook::react::SurfaceHandler const &)surfaceHandler; - (void)onAnimationStarted; diff --git a/React/Fabric/RCTScheduler.mm b/React/Fabric/RCTScheduler.mm index 3e7281be63c02c..b9d38d6cd869ef 100644 --- a/React/Fabric/RCTScheduler.mm +++ b/React/Fabric/RCTScheduler.mm @@ -139,43 +139,14 @@ - (void)dealloc _animationDriver = nullptr; } -- (void)startSurfaceWithSurfaceId:(SurfaceId)surfaceId - moduleName:(NSString *)moduleName - initialProps:(NSDictionary *)initialProps - layoutConstraints:(LayoutConstraints)layoutConstraints - layoutContext:(LayoutContext)layoutContext +- (void)registerSurface:(facebook::react::SurfaceHandler const &)surfaceHandler { - SystraceSection s("-[RCTScheduler startSurfaceWithSurfaceId:...]"); - - auto props = convertIdToFollyDynamic(initialProps); - _scheduler->startSurface(surfaceId, RCTStringFromNSString(moduleName), props, layoutConstraints, layoutContext); - - _scheduler->findMountingCoordinator(surfaceId)->setMountingOverrideDelegate(_animationDriver); - - _scheduler->renderTemplateToSurface( - surfaceId, props.getDefault("navigationConfig").getDefault("initialUITemplate", "").getString()); -} - -- (void)stopSurfaceWithSurfaceId:(SurfaceId)surfaceId -{ - SystraceSection s("-[RCTScheduler stopSurfaceWithSurfaceId:]"); - _scheduler->stopSurface(surfaceId); -} - -- (CGSize)measureSurfaceWithLayoutConstraints:(LayoutConstraints)layoutConstraints - layoutContext:(LayoutContext)layoutContext - surfaceId:(SurfaceId)surfaceId -{ - SystraceSection s("-[RCTScheduler measureSurfaceWithLayoutConstraints:]"); - return RCTCGSizeFromSize(_scheduler->measureSurface(surfaceId, layoutConstraints, layoutContext)); + _scheduler->registerSurface(surfaceHandler); } -- (void)constraintSurfaceLayoutWithLayoutConstraints:(LayoutConstraints)layoutConstraints - layoutContext:(LayoutContext)layoutContext - surfaceId:(SurfaceId)surfaceId +- (void)unregisterSurface:(facebook::react::SurfaceHandler const &)surfaceHandler { - SystraceSection s("-[RCTScheduler constraintSurfaceLayoutWithLayoutConstraints:]"); - _scheduler->constraintSurfaceLayout(surfaceId, layoutConstraints, layoutContext); + _scheduler->unregisterSurface(surfaceHandler); } - (ComponentDescriptor const *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN:(ComponentHandle)handle @@ -183,9 +154,9 @@ - (ComponentDescriptor const *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_I return _scheduler->findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(handle); } -- (MountingCoordinator::Shared)mountingCoordinatorWithSurfaceId:(SurfaceId)surfaceId +- (void)setupAnimationDriver:(facebook::react::SurfaceHandler const &)surfaceHandler { - return _scheduler->findMountingCoordinator(surfaceId); + surfaceHandler.getMountingCoordinator()->setMountingOverrideDelegate(_animationDriver); } - (void)onAnimationStarted diff --git a/React/Fabric/RCTSurfacePresenter.h b/React/Fabric/RCTSurfacePresenter.h index 6293ef6167ce89..0053a376ee1c17 100644 --- a/React/Fabric/RCTSurfacePresenter.h +++ b/React/Fabric/RCTSurfacePresenter.h @@ -11,6 +11,7 @@ #import #import #import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -45,34 +46,25 @@ NS_ASSUME_NONNULL_BEGIN @interface RCTSurfacePresenter (Surface) -/** +/* * Surface uses these methods to register itself in the Presenter. */ - (void)registerSurface:(RCTFabricSurface *)surface; - (void)unregisterSurface:(RCTFabricSurface *)surface; -- (void)setProps:(NSDictionary *)props surface:(RCTFabricSurface *)surface; +@property (readonly) RCTMountingManager *mountingManager; - (nullable RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag; -/** - * Measures the Surface with given constraints. - */ -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize - maximumSize:(CGSize)maximumSize - surface:(RCTFabricSurface *)surface; - -/** - * Sets `minimumSize` and `maximumSize` layout constraints for the Surface. - */ -- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface; - - (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props; -- (BOOL)synchronouslyWaitSurface:(RCTFabricSurface *)surface timeout:(NSTimeInterval)timeout; +- (void)setupAnimationDriverWithSurfaceHandler:(facebook::react::SurfaceHandler const &)surfaceHandler; +/* + * Deprecated. + * Use `RCTMountingTransactionObserverCoordinator` instead. + */ - (void)addObserver:(id)observer; - - (void)removeObserver:(id)observer; /* diff --git a/React/Fabric/RCTSurfacePresenter.mm b/React/Fabric/RCTSurfacePresenter.mm index e982243d62e849..bd11901c67ff07 100644 --- a/React/Fabric/RCTSurfacePresenter.mm +++ b/React/Fabric/RCTSurfacePresenter.mm @@ -40,25 +40,6 @@ using namespace facebook::react; -static inline LayoutConstraints RCTGetLayoutConstraintsForSize(CGSize minimumSize, CGSize maximumSize) -{ - return { - .minimumSize = RCTSizeFromCGSize(minimumSize), - .maximumSize = RCTSizeFromCGSize(maximumSize), - .layoutDirection = RCTLayoutDirection([[RCTI18nUtil sharedInstance] isRTL]), - }; -} - -static inline LayoutContext RCTGetLayoutContext(CGPoint viewportOffset) -{ - return { - .pointScaleFactor = RCTScreenScale(), - .swapLeftAndRightInRTL = - [[RCTI18nUtil sharedInstance] isRTL] && [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL], - .fontSizeMultiplier = RCTFontSizeMultiplier(), - .viewportOffset = RCTPointFromCGPoint(viewportOffset)}; -} - static dispatch_queue_t RCTGetBackgroundQueue() { static dispatch_queue_t queue; @@ -119,16 +100,16 @@ - (instancetype)initWithContextContainer:(ContextContainer::Shared)contextContai _observers = [NSMutableArray array]; _scheduler = [self _createScheduler]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(_handleContentSizeCategoryDidChangeNotification:) - name:UIContentSizeCategoryDidChangeNotification - object:nil]; } return self; } +- (RCTMountingManager *)mountingManager +{ + return _mountingManager; +} + - (RCTScheduler *_Nullable)_scheduler { std::lock_guard lock(_schedulerAccessMutex); @@ -163,10 +144,10 @@ - (void)setRuntimeExecutor:(RuntimeExecutor)runtimeExecutor - (void)registerSurface:(RCTFabricSurface *)surface { - RCTScheduler *scheduler = [self _scheduler]; [_surfaceRegistry registerSurface:surface]; + RCTScheduler *scheduler = [self _scheduler]; if (scheduler) { - [self _startSurface:surface scheduler:scheduler]; + [scheduler registerSurface:surface.surfaceHandler]; } } @@ -174,54 +155,16 @@ - (void)unregisterSurface:(RCTFabricSurface *)surface { RCTScheduler *scheduler = [self _scheduler]; if (scheduler) { - [self _stopSurface:surface scheduler:scheduler]; + [scheduler unregisterSurface:surface.surfaceHandler]; } [_surfaceRegistry unregisterSurface:surface]; } -- (void)setProps:(NSDictionary *)props surface:(RCTFabricSurface *)surface -{ - RCTScheduler *scheduler = [self _scheduler]; - if (scheduler) { - [self _stopSurface:surface scheduler:scheduler]; - [self _startSurface:surface scheduler:scheduler]; - } -} - - (RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag { return [_surfaceRegistry surfaceForRootTag:rootTag]; } -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize - maximumSize:(CGSize)maximumSize - surface:(RCTFabricSurface *)surface -{ - RCTScheduler *scheduler = [self _scheduler]; - if (!scheduler) { - return minimumSize; - } - LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset); - LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(minimumSize, maximumSize); - return [scheduler measureSurfaceWithLayoutConstraints:layoutConstraints - layoutContext:layoutContext - surfaceId:surface.rootTag]; -} - -- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize surface:(RCTFabricSurface *)surface -{ - RCTScheduler *scheduler = [self _scheduler]; - if (!scheduler) { - return; - } - - LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset); - LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(minimumSize, maximumSize); - [scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints - layoutContext:layoutContext - surfaceId:surface.rootTag]; -} - - (UIView *)findComponentViewWithTag_DO_NOT_USE_DEPRECATED:(NSInteger)tag { UIView *componentView = @@ -253,22 +196,9 @@ - (BOOL)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictiona return YES; } -- (BOOL)synchronouslyWaitSurface:(RCTFabricSurface *)surface timeout:(NSTimeInterval)timeout +- (void)setupAnimationDriverWithSurfaceHandler:(facebook::react::SurfaceHandler const &)surfaceHandler { - RCTScheduler *scheduler = [self _scheduler]; - if (!scheduler) { - return NO; - } - - auto mountingCoordinator = [scheduler mountingCoordinatorWithSurfaceId:surface.rootTag]; - - if (!mountingCoordinator->waitForTransaction(std::chrono::duration(timeout))) { - return NO; - } - - [_mountingManager scheduleTransaction:mountingCoordinator]; - - return YES; + [[self _scheduler] setupAnimationDriver:surfaceHandler]; } - (BOOL)suspend @@ -377,39 +307,12 @@ - (RCTScheduler *)_createScheduler return scheduler; } -- (void)_startSurface:(RCTFabricSurface *)surface scheduler:(RCTScheduler *)scheduler -{ - RCTMountingManager *mountingManager = _mountingManager; - RCTExecuteOnMainQueue(^{ - [mountingManager attachSurfaceToView:surface.view surfaceId:surface.rootTag]; - }); - - LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset); - - LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(surface.minimumSize, surface.maximumSize); - - [scheduler startSurfaceWithSurfaceId:surface.rootTag - moduleName:surface.moduleName - initialProps:surface.properties - layoutConstraints:layoutConstraints - layoutContext:layoutContext]; -} - -- (void)_stopSurface:(RCTFabricSurface *)surface scheduler:(RCTScheduler *)scheduler -{ - [scheduler stopSurfaceWithSurfaceId:surface.rootTag]; - - RCTMountingManager *mountingManager = _mountingManager; - RCTExecuteOnMainQueue(^{ - [mountingManager detachSurfaceFromView:surface.view surfaceId:surface.rootTag]; - }); -} - - (void)_startAllSurfacesWithScheduler:(RCTScheduler *)scheduler { [_surfaceRegistry enumerateWithBlock:^(NSEnumerator *enumerator) { for (RCTFabricSurface *surface in enumerator) { - [self _startSurface:surface scheduler:scheduler]; + [scheduler registerSurface:surface.surfaceHandler]; + [surface start]; } }]; } @@ -418,24 +321,8 @@ - (void)_stopAllSurfacesWithScheduler:(RCTScheduler *)scheduler { [_surfaceRegistry enumerateWithBlock:^(NSEnumerator *enumerator) { for (RCTFabricSurface *surface in enumerator) { - [self _stopSurface:surface scheduler:scheduler]; - } - }]; -} - -- (void)_handleContentSizeCategoryDidChangeNotification:(NSNotification *)notification -{ - RCTScheduler *scheduler = [self _scheduler]; - - [_surfaceRegistry enumerateWithBlock:^(NSEnumerator *enumerator) { - for (RCTFabricSurface *surface in enumerator) { - LayoutContext layoutContext = RCTGetLayoutContext(surface.viewportOffset); - - LayoutConstraints layoutConstraints = RCTGetLayoutConstraintsForSize(surface.minimumSize, surface.maximumSize); - - [scheduler constraintSurfaceLayoutWithLayoutConstraints:layoutConstraints - layoutContext:layoutContext - surfaceId:surface.rootTag]; + [surface stop]; + [scheduler unregisterSurface:surface.surfaceHandler]; } }]; } diff --git a/React/Fabric/Surface/RCTFabricSurface.h b/React/Fabric/Surface/RCTFabricSurface.h index 1c3e4af43f71dd..77b3c906cc7dd0 100644 --- a/React/Fabric/Surface/RCTFabricSurface.h +++ b/React/Fabric/Surface/RCTFabricSurface.h @@ -8,6 +8,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -128,12 +129,7 @@ NS_ASSUME_NONNULL_BEGIN @interface RCTFabricSurface (Internal) -/** - * Sets and clears given stage flags (bitmask). - * Returns `YES` if the actual state was changed. - */ -- (BOOL)_setStage:(RCTSurfaceStage)stage; -- (BOOL)_unsetStage:(RCTSurfaceStage)stage; +- (facebook::react::SurfaceHandler const &)surfaceHandler; @end diff --git a/React/Fabric/Surface/RCTFabricSurface.mm b/React/Fabric/Surface/RCTFabricSurface.mm index 616945339cd760..ba325ac55c8bc1 100644 --- a/React/Fabric/Surface/RCTFabricSurface.mm +++ b/React/Fabric/Surface/RCTFabricSurface.mm @@ -10,6 +10,10 @@ #import #import +#import +#import +#import +#import #import #import #import @@ -23,26 +27,25 @@ using namespace facebook::react; @implementation RCTFabricSurface { - // Immutable __weak RCTSurfacePresenter *_surfacePresenter; - NSString *_moduleName; - - // Protected by the `_mutex` - std::mutex _mutex; - RCTSurfaceStage _stage; - NSDictionary *_properties; - CGSize _minimumSize; - CGSize _maximumSize; - CGPoint _viewportOffset; - CGSize _intrinsicSize; - - // The Main thread only + + // `SurfaceHandler` is a thread-safe object, so we don't need additional synchronization. + // Objective-C++ classes cannot have instance variables without default constructors, + // hence we wrap a value into `optional` to workaround it. + better::optional _surfaceHandler; + + // Protects Surface's start and stop processes. + // Even though SurfaceHandler is tread-safe, it will crash if we try to stop a surface that is not running. + // To make the API easy to use, we check the status of the surface before calling `start` or `stop`, + // and we need this mutex to prevent races. + std::mutex _surfaceMutex; + + // Can be accessed from the main thread only. RCTSurfaceView *_Nullable _view; RCTSurfaceTouchHandler *_Nullable _touchHandler; } @synthesize delegate = _delegate; -@synthesize rootTag = _rootTag; - (instancetype)initWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter moduleName:(NSString *)moduleName @@ -50,15 +53,19 @@ - (instancetype)initWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter { if (self = [super init]) { _surfacePresenter = surfacePresenter; - _moduleName = moduleName; - _properties = [initialProperties copy]; - _rootTag = [RCTAllocateRootViewTag() integerValue]; - _minimumSize = CGSizeZero; + _surfaceHandler = + SurfaceHandler{RCTStringFromNSString(moduleName), (SurfaceId)[RCTAllocateRootViewTag() integerValue]}; + _surfaceHandler->setProps(convertIdToFollyDynamic(initialProperties)); - _maximumSize = CGSizeMake(CGFLOAT_MAX, CGFLOAT_MAX); + [_surfacePresenter registerSurface:self]; - _stage = RCTSurfaceStageSurfaceDidInitialize; + [self _updateLayoutContext]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleContentSizeCategoryDidChangeNotification:) + name:UIContentSizeCategoryDidChangeNotification + object:nil]; } return self; @@ -66,41 +73,62 @@ - (instancetype)initWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter - (void)resetWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter { - _surfacePresenter = surfacePresenter; - _stage = RCTSurfaceStageSurfaceDidInitialize; _view = nil; + _surfacePresenter = surfacePresenter; + [_surfacePresenter registerSurface:self]; } +- (void)dealloc +{ + [_surfacePresenter unregisterSurface:self]; +} + +#pragma mark - Life-cycle management + - (BOOL)start { - if (![self _setStage:RCTSurfaceStageRunning]) { + std::lock_guard lock(_surfaceMutex); + + if (_surfaceHandler->getStatus() != SurfaceHandler::Status::Registered) { return NO; } - [_surfacePresenter registerSurface:self]; + _surfaceHandler->start(); + [self _propagateStageChange]; + + RCTExecuteOnMainQueue(^{ + [self->_surfacePresenter.mountingManager attachSurfaceToView:self.view + surfaceId:self->_surfaceHandler->getSurfaceId()]; + }); + + [_surfacePresenter setupAnimationDriverWithSurfaceHandler:*_surfaceHandler]; return YES; } - (BOOL)stop { - if (![self _unsetStage:RCTSurfaceStageRunning]) { + std::lock_guard lock(_surfaceMutex); + + if (_surfaceHandler->getStatus() != SurfaceHandler::Status::Running) { return NO; } - [_surfacePresenter unregisterSurface:self]; - return YES; -} + _surfaceHandler->stop(); + [self _propagateStageChange]; -- (void)dealloc -{ - [self stop]; + RCTExecuteOnMainQueue(^{ + [self->_surfacePresenter.mountingManager detachSurfaceFromView:self.view + surfaceId:self->_surfaceHandler->getSurfaceId()]; + }); + + return YES; } #pragma mark - Immutable Properties (no need to enforce synchronization) - (NSString *)moduleName { - return _moduleName; + return RCTNSStringFromString(_surfaceHandler->getModuleName()); } #pragma mark - Main-Threaded Routines @@ -122,49 +150,13 @@ - (RCTSurfaceView *)view - (RCTSurfaceStage)stage { - std::lock_guard lock(_mutex); - return _stage; -} - -- (BOOL)_setStage:(RCTSurfaceStage)stage -{ - return [self _setStage:stage setOrUnset:YES]; + return _surfaceHandler->getStatus() == SurfaceHandler::Status::Running ? RCTSurfaceStageRunning + : RCTSurfaceStagePreparing; } -- (BOOL)_unsetStage:(RCTSurfaceStage)stage +- (void)_propagateStageChange { - return [self _setStage:stage setOrUnset:NO]; -} - -- (BOOL)_setStage:(RCTSurfaceStage)stage setOrUnset:(BOOL)setOrUnset -{ - RCTSurfaceStage updatedStage; - { - std::lock_guard lock(_mutex); - - if (setOrUnset) { - updatedStage = (RCTSurfaceStage)(_stage | stage); - } else { - updatedStage = (RCTSurfaceStage)(_stage & ~stage); - } - - if (updatedStage == _stage) { - return NO; - } - - _stage = updatedStage; - } - - [self _propagateStageChange:updatedStage]; - return YES; -} - -- (void)_propagateStageChange:(RCTSurfaceStage)stage -{ - // Updating the `view` - RCTExecuteOnMainQueue(^{ - self->_view.stage = stage; - }); + RCTSurfaceStage stage = self.stage; // Notifying the `delegate` id delegate = self.delegate; @@ -173,114 +165,113 @@ - (void)_propagateStageChange:(RCTSurfaceStage)stage } } +- (void)_updateLayoutContext +{ + auto layoutConstraints = _surfaceHandler->getLayoutConstraints(); + auto layoutContext = _surfaceHandler->getLayoutContext(); + + layoutContext.pointScaleFactor = RCTScreenScale(); + layoutContext.swapLeftAndRightInRTL = + [[RCTI18nUtil sharedInstance] isRTL] && [[RCTI18nUtil sharedInstance] doLeftAndRightSwapInRTL]; + layoutContext.fontSizeMultiplier = RCTFontSizeMultiplier(); + + _surfaceHandler->constraintLayout(layoutConstraints, layoutContext); +} + #pragma mark - Properties Management - (NSDictionary *)properties { - std::lock_guard lock(_mutex); - return _properties; + return convertFollyDynamicToId(_surfaceHandler->getProps()); } - (void)setProperties:(NSDictionary *)properties { - { - std::lock_guard lock(_mutex); + _surfaceHandler->setProps(convertIdToFollyDynamic(properties)); +} + +#pragma mark - Layout + +- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize viewportOffset:(CGPoint)viewportOffset +{ + auto layoutConstraints = _surfaceHandler->getLayoutConstraints(); + auto layoutContext = _surfaceHandler->getLayoutContext(); - if ([properties isEqualToDictionary:_properties]) { - return; - } + layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize); + layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize); - _properties = [properties copy]; + if (!isnan(viewportOffset.x) && !isnan(viewportOffset.y)) { + layoutContext.viewportOffset = RCTPointFromCGPoint(viewportOffset); } - [_surfacePresenter setProps:properties surface:self]; + _surfaceHandler->constraintLayout(layoutConstraints, layoutContext); } -#pragma mark - Layout - -- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize +- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize { - return [_surfacePresenter sizeThatFitsMinimumSize:minimumSize maximumSize:maximumSize surface:self]; + [self setMinimumSize:minimumSize maximumSize:maximumSize viewportOffset:CGPointMake(NAN, NAN)]; } -#pragma mark - Size Constraints - - (void)setSize:(CGSize)size { - [self setMinimumSize:size maximumSize:size viewportOffset:_viewportOffset]; + [self setMinimumSize:size maximumSize:size]; } -- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize viewportOffset:(CGPoint)viewportOffset +- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize { - { - std::lock_guard lock(_mutex); - if (CGSizeEqualToSize(minimumSize, _minimumSize) && CGSizeEqualToSize(maximumSize, _maximumSize) && - CGPointEqualToPoint(viewportOffset, _viewportOffset)) { - return; - } - - _maximumSize = maximumSize; - _minimumSize = minimumSize; - _viewportOffset = viewportOffset; - } + auto layoutConstraints = _surfaceHandler->getLayoutConstraints(); + auto layoutContext = _surfaceHandler->getLayoutContext(); - [_surfacePresenter setMinimumSize:minimumSize maximumSize:maximumSize surface:self]; -} + layoutConstraints.minimumSize = RCTSizeFromCGSize(minimumSize); + layoutConstraints.maximumSize = RCTSizeFromCGSize(maximumSize); -- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize -{ - [self setMinimumSize:minimumSize maximumSize:maximumSize viewportOffset:_viewportOffset]; + return RCTCGSizeFromSize(_surfaceHandler->measure(layoutConstraints, layoutContext)); } - (CGSize)minimumSize { - std::lock_guard lock(_mutex); - return _minimumSize; + return RCTCGSizeFromSize(_surfaceHandler->getLayoutConstraints().minimumSize); } - (CGSize)maximumSize { - std::lock_guard lock(_mutex); - return _maximumSize; + return RCTCGSizeFromSize(_surfaceHandler->getLayoutConstraints().maximumSize); } - (CGPoint)viewportOffset { - std::lock_guard lock(_mutex); - return _viewportOffset; + return RCTCGPointFromPoint(_surfaceHandler->getLayoutContext().viewportOffset); } -#pragma mark - intrinsicSize +#pragma mark - Synchronous Waiting -- (void)setIntrinsicSize:(CGSize)intrinsicSize +- (BOOL)synchronouslyWaitFor:(NSTimeInterval)timeout { - { - std::lock_guard lock(_mutex); - if (CGSizeEqualToSize(intrinsicSize, _intrinsicSize)) { - return; - } + auto mountingCoordinator = _surfaceHandler->getMountingCoordinator(); - _intrinsicSize = intrinsicSize; + if (!mountingCoordinator) { + return NO; } - // Notifying `delegate` - id delegate = self.delegate; - if ([delegate respondsToSelector:@selector(surface:didChangeIntrinsicSize:)]) { - [delegate surface:(RCTSurface *)(id)self didChangeIntrinsicSize:intrinsicSize]; + if (!mountingCoordinator->waitForTransaction(std::chrono::duration(timeout))) { + return NO; } + + [_surfacePresenter.mountingManager scheduleTransaction:mountingCoordinator]; + + return YES; } -- (CGSize)intrinsicSize +- (void)handleContentSizeCategoryDidChangeNotification:(NSNotification *)notification { - std::lock_guard lock(_mutex); - return _intrinsicSize; + [self _updateLayoutContext]; } -#pragma mark - Synchronous Waiting +#pragma mark - Private -- (BOOL)synchronouslyWaitFor:(NSTimeInterval)timeout +- (SurfaceHandler const &)surfaceHandler; { - return [_surfacePresenter synchronouslyWaitSurface:self timeout:timeout]; + return *_surfaceHandler; } #pragma mark - Deprecated @@ -296,7 +287,12 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge - (NSNumber *)rootViewTag { - return @(_rootTag); + return @(_surfaceHandler->getSurfaceId()); +} + +- (NSInteger)rootTag +{ + return (NSInteger)(_surfaceHandler->getSurfaceId()); } @end From 86321a35c03df340b6c1ea740ea7f29e2659b0ab Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Wed, 24 Feb 2021 12:16:25 -0800 Subject: [PATCH 02/51] Fix text in ReactTextView being vertically displayed Summary: ## Issue: Sometimes ReactTextView are vertically displayed as one column with bridgeless. ## Root cause: After debugging, I found out this is caused by a workaround in 2016 to fix a crash caused by mLayout occasionally being non-null and triggers relayout during setText. https://github.com/facebook/react-native/pull/7011 ## Fix Revert previous hack, if the crash happens again I'll try to fix it. Changelog: [Android][Fixed] - Fix text in ReactTextView sometimes being vertically displayed Reviewed By: mdvacca Differential Revision: D26581756 fbshipit-source-id: a373d84dc1ab3d787bda7ec82f2d0865a354cf60 --- .../facebook/react/config/ReactFeatureFlags.java | 3 +++ .../facebook/react/views/text/ReactTextView.java | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index c195ab8e7bc115..5f493dbf55ee83 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -59,4 +59,7 @@ public class ReactFeatureFlags { /** Enables a more aggressive cleanup during destruction of ReactContext */ public static boolean enableReactContextCleanupFix = false; + + /** Enables setting layout params to empty to fix a crash */ + public static boolean enableSettingEmptyLayoutParams = false; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index f7a0a18995fe75..85e5cdd62e8954 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -31,6 +31,7 @@ import com.facebook.react.bridge.WritableArray; import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.ReactConstants; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactCompoundView; import com.facebook.react.uimanager.UIManagerModule; @@ -265,11 +266,13 @@ public int compare(Object o1, Object o2) { public void setText(ReactTextUpdate update) { mContainsImages = update.containsImages(); - // Android's TextView crashes when it tries to relayout if LayoutParams are - // null; explicitly set the LayoutParams to prevent this crash. See: - // https://github.com/facebook/react-native/pull/7011 - if (getLayoutParams() == null) { - setLayoutParams(EMPTY_LAYOUT_PARAMS); + if (ReactFeatureFlags.enableSettingEmptyLayoutParams) { + // Android's TextView crashes when it tries to relayout if LayoutParams are + // null; explicitly set the LayoutParams to prevent this crash. See: + // https://github.com/facebook/react-native/pull/7011 + if (getLayoutParams() == null) { + setLayoutParams(EMPTY_LAYOUT_PARAMS); + } } Spannable spannable = update.getText(); if (mLinkifyMaskType > 0) { From 3399896ae756719b238e837001077a46508849be Mon Sep 17 00:00:00 2001 From: Janic Duplessis Date: Wed, 24 Feb 2021 12:20:54 -0800 Subject: [PATCH 03/51] Update flipper in RNTester and template (#31010) Summary: allow-large-files RN Tester is using an old version of Flipper. This will help testing regressions in the latest version (which is installed when starting a new project). This also fixes an issue where libevent is incompatible between the one in flipper and when using hermes on iOS. To fix it I changed to use the version published on cocoapods instead of using a local podspec (see https://github.com/facebook/flipper/issues/1916). ## Changelog [General] [Changed] - Update flipper Pull Request resolved: https://github.com/facebook/react-native/pull/31010 Test Plan: - Tested that RN tester builds and flipper works with hermes enabled / disabled and fabric on iOS - Tested that RN tester builds and flipper works on Android Reviewed By: fkgozali Differential Revision: D26592317 Pulled By: PeteTheHeat fbshipit-source-id: 2cd278c7a51b1859dab0465846b061221f07d3f6 --- packages/rn-tester/Podfile | 4 +- packages/rn-tester/Podfile.lock | 104 ++-- .../RNTesterPods.xcodeproj/project.pbxproj | 30 +- .../rn-tester/android/app/gradle.properties | 2 +- scripts/react_native_pods.rb | 8 +- template/android/gradle.properties | 2 +- third-party-podspecs/libevent.podspec | 565 ------------------ 7 files changed, 84 insertions(+), 631 deletions(-) delete mode 100644 third-party-podspecs/libevent.podspec diff --git a/packages/rn-tester/Podfile b/packages/rn-tester/Podfile index 63b8dc52935978..ae885b01454857 100644 --- a/packages/rn-tester/Podfile +++ b/packages/rn-tester/Podfile @@ -57,7 +57,5 @@ target 'RNTesterIntegrationTests' do end post_install do |installer| - if !USE_FRAMEWORKS - flipper_post_install(installer) - end + react_native_post_install(installer) end diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index af9913d9812217..d7d4889b4c7b54 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -1,7 +1,6 @@ PODS: - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.5) - - CocoaLibEvent (1.0.0) - DoubleConversion (1.1.6) - FBLazyVector (1000.0.0) - FBReactNativeSpec (1000.0.0): @@ -11,56 +10,55 @@ PODS: - React-Core (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) - - Flipper (0.54.0): - - Flipper-Folly (~> 2.2) - - Flipper-RSocket (~> 1.1) + - Flipper (0.75.1): + - Flipper-Folly (~> 2.5) + - Flipper-RSocket (~> 1.3) - Flipper-DoubleConversion (1.1.7) - - Flipper-Folly (2.3.0): + - Flipper-Folly (2.5.1): - boost-for-react-native - - CocoaLibEvent (~> 1.0) - Flipper-DoubleConversion - Flipper-Glog - - OpenSSL-Universal (= 1.0.2.20) + - libevent (~> 2.1.12) + - OpenSSL-Universal (= 1.1.180) - Flipper-Glog (0.3.6) - Flipper-PeerTalk (0.0.4) - - Flipper-RSocket (1.1.0): - - Flipper-Folly (~> 2.2) - - FlipperKit (0.54.0): - - FlipperKit/Core (= 0.54.0) - - FlipperKit/Core (0.54.0): - - Flipper (~> 0.54.0) + - Flipper-RSocket (1.3.0): + - Flipper-Folly (~> 2.5) + - FlipperKit (0.75.1): + - FlipperKit/Core (= 0.75.1) + - FlipperKit/Core (0.75.1): + - Flipper (~> 0.75.1) - FlipperKit/CppBridge - FlipperKit/FBCxxFollyDynamicConvert - FlipperKit/FBDefines - FlipperKit/FKPortForwarding - - FlipperKit/CppBridge (0.54.0): - - Flipper (~> 0.54.0) - - FlipperKit/FBCxxFollyDynamicConvert (0.54.0): - - Flipper-Folly (~> 2.2) - - FlipperKit/FBDefines (0.54.0) - - FlipperKit/FKPortForwarding (0.54.0): + - FlipperKit/CppBridge (0.75.1): + - Flipper (~> 0.75.1) + - FlipperKit/FBCxxFollyDynamicConvert (0.75.1): + - Flipper-Folly (~> 2.5) + - FlipperKit/FBDefines (0.75.1) + - FlipperKit/FKPortForwarding (0.75.1): - CocoaAsyncSocket (~> 7.6) - Flipper-PeerTalk (~> 0.0.4) - - FlipperKit/FlipperKitHighlightOverlay (0.54.0) - - FlipperKit/FlipperKitLayoutPlugin (0.54.0): + - FlipperKit/FlipperKitHighlightOverlay (0.75.1) + - FlipperKit/FlipperKitLayoutPlugin (0.75.1): - FlipperKit/Core - FlipperKit/FlipperKitHighlightOverlay - FlipperKit/FlipperKitLayoutTextSearchable - YogaKit (~> 1.18) - - FlipperKit/FlipperKitLayoutTextSearchable (0.54.0) - - FlipperKit/FlipperKitNetworkPlugin (0.54.0): + - FlipperKit/FlipperKitLayoutTextSearchable (0.75.1) + - FlipperKit/FlipperKitNetworkPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/FlipperKitReactPlugin (0.54.0): + - FlipperKit/FlipperKitReactPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/FlipperKitUserDefaultsPlugin (0.54.0): + - FlipperKit/FlipperKitUserDefaultsPlugin (0.75.1): - FlipperKit/Core - - FlipperKit/SKIOSNetworkPlugin (0.54.0): + - FlipperKit/SKIOSNetworkPlugin (0.75.1): - FlipperKit/Core - FlipperKit/FlipperKitNetworkPlugin - glog (0.3.5) - - OpenSSL-Universal (1.0.2.20): - - OpenSSL-Universal/Static (= 1.0.2.20) - - OpenSSL-Universal/Static (1.0.2.20) + - libevent (2.1.12) + - OpenSSL-Universal (1.1.180) - RCT-Folly (2020.01.13.00): - boost-for-react-native - DoubleConversion @@ -663,25 +661,25 @@ DEPENDENCIES: - DoubleConversion (from `../../third-party-podspecs/DoubleConversion.podspec`) - FBLazyVector (from `../../Libraries/FBLazyVector`) - FBReactNativeSpec (from `../../React/FBReactNativeSpec`) - - Flipper (~> 0.54.0) + - Flipper (~> 0.75.1) - Flipper-DoubleConversion (= 1.1.7) - - Flipper-Folly (~> 2.2) + - Flipper-Folly (~> 2.5) - Flipper-Glog (= 0.3.6) - Flipper-PeerTalk (~> 0.0.4) - - Flipper-RSocket (~> 1.1) - - FlipperKit (~> 0.54.0) - - FlipperKit/Core (~> 0.54.0) - - FlipperKit/CppBridge (~> 0.54.0) - - FlipperKit/FBCxxFollyDynamicConvert (~> 0.54.0) - - FlipperKit/FBDefines (~> 0.54.0) - - FlipperKit/FKPortForwarding (~> 0.54.0) - - FlipperKit/FlipperKitHighlightOverlay (~> 0.54.0) - - FlipperKit/FlipperKitLayoutPlugin (~> 0.54.0) - - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.54.0) - - FlipperKit/FlipperKitNetworkPlugin (~> 0.54.0) - - FlipperKit/FlipperKitReactPlugin (~> 0.54.0) - - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.54.0) - - FlipperKit/SKIOSNetworkPlugin (~> 0.54.0) + - Flipper-RSocket (~> 1.3) + - FlipperKit (~> 0.75.1) + - FlipperKit/Core (~> 0.75.1) + - FlipperKit/CppBridge (~> 0.75.1) + - FlipperKit/FBCxxFollyDynamicConvert (~> 0.75.1) + - FlipperKit/FBDefines (~> 0.75.1) + - FlipperKit/FKPortForwarding (~> 0.75.1) + - FlipperKit/FlipperKitHighlightOverlay (~> 0.75.1) + - FlipperKit/FlipperKitLayoutPlugin (~> 0.75.1) + - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.75.1) + - FlipperKit/FlipperKitNetworkPlugin (~> 0.75.1) + - FlipperKit/FlipperKitReactPlugin (~> 0.75.1) + - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.75.1) + - FlipperKit/SKIOSNetworkPlugin (~> 0.75.1) - glog (from `../../third-party-podspecs/glog.podspec`) - RCT-Folly (from `../../third-party-podspecs/RCT-Folly.podspec`) - RCT-Folly/Fabric (from `../../third-party-podspecs/RCT-Folly.podspec`) @@ -722,7 +720,6 @@ SPEC REPOS: trunk: - boost-for-react-native - CocoaAsyncSocket - - CocoaLibEvent - Flipper - Flipper-DoubleConversion - Flipper-Folly @@ -730,6 +727,7 @@ SPEC REPOS: - Flipper-PeerTalk - Flipper-RSocket - FlipperKit + - libevent - OpenSSL-Universal - YogaKit @@ -804,19 +802,19 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: cde416483dac037923206447da6e1454df403714 FBLazyVector: 91e874a8823933a268c38765a88cbd5dba1fa024 FBReactNativeSpec: 6793f00102a091fb931674853172fb22e5a2c4cf - Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365 + Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 - Flipper-Folly: e4493b013c02d9347d5e0cb4d128680239f6c78a + Flipper-Folly: f7a3caafbd74bda4827954fd7a6e000e36355489 Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6 Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 - Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7 - FlipperKit: ab353d41aea8aae2ea6daaf813e67496642f3d7d + Flipper-RSocket: 602921fee03edacf18f5d6f3d3594ba477f456e5 + FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 - OpenSSL-Universal: ff34003318d5e1163e9529b08470708e389ffcdd + libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 + OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c RCTRequired: 047bd218d23dbe95d2a933eb5030a269d2a42929 RCTTypeSafety: c2fc670603ca48eb4c1230091eaffb422e6d0d4d @@ -848,6 +846,6 @@ SPEC CHECKSUMS: Yoga: 69c2b21737d8220f647e61141aec8c28f7249ef2 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a -PODFILE CHECKSUM: 799678aa4c11e7c6d8a431a3883e94b09b8dd0f1 +PODFILE CHECKSUM: 6e910a576b7db9347c60dfc58f7852f692200116 COCOAPODS: 1.10.1 diff --git a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj index 47fb7dd64bf7a9..e59f85b3e91717 100644 --- a/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj +++ b/packages/rn-tester/RNTesterPods.xcodeproj/project.pbxproj @@ -77,6 +77,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 0CC3BE1A25DDB68A0033CAEB /* RNTester.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; name = RNTester.entitlements; path = RNTester/RNTester.entitlements; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* RNTester.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNTester.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNTester/AppDelegate.h; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNTester/Info.plist; sourceTree = ""; }; @@ -219,6 +220,7 @@ 13B07FAE1A68108700A75B9A /* RNTester */ = { isa = PBXGroup; children = ( + 0CC3BE1A25DDB68A0033CAEB /* RNTester.entitlements */, E771AEEA22B44E3100EA1189 /* Info.plist */, 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 5C60EB1B226440DB0018C04F /* AppDelegate.mm */, @@ -406,6 +408,7 @@ 68CD48B71D2BCB2C007E06A9 /* Build JS Bundle */, 5CF0FD27207FC6EC00C13D65 /* Start Metro */, CD2B49A7F80C8171E7A5B233 /* [CP] Copy Pods Resources */, + FCBC860F39D3E385BA7C6FF7 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -665,6 +668,23 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + FCBC860F39D3E385BA7C6FF7 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNTester/Pods-RNTester-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -748,15 +768,15 @@ isa = XCBuildConfiguration; baseConfigurationReference = 98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", + "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -781,9 +801,8 @@ isa = XCBuildConfiguration; baseConfigurationReference = 5BEC8567F3741044B6A5EFC5 /* Pods-RNTester.release.xcconfig */; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_CXX_LANGUAGE_STANDARD = "c++14"; + CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; DEVELOPMENT_TEAM = ""; EXCLUDED_ARCHS = ""; INFOPLIST_FILE = "$(SRCROOT)/RNTester/Info.plist"; @@ -791,6 +810,7 @@ LD_RUNPATH_SEARCH_PATHS = ( /usr/lib/swift, "$(inherited)", + "@executable_path/Frameworks", ); LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -847,6 +867,7 @@ ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 "; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -930,6 +951,7 @@ ENABLE_BITCODE = NO; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "arm64 "; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES; diff --git a/packages/rn-tester/android/app/gradle.properties b/packages/rn-tester/android/app/gradle.properties index 5c93b3bca832dc..9eea6a6e70f5db 100644 --- a/packages/rn-tester/android/app/gradle.properties +++ b/packages/rn-tester/android/app/gradle.properties @@ -10,4 +10,4 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.54.0 +FLIPPER_VERSION=0.75.1 diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index dde169e9be1d6f..2a2b04e2b350fa 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -64,17 +64,17 @@ def use_react_native! (options={}) if hermes_enabled pod 'React-hermes', :path => "#{prefix}/ReactCommon/hermes" pod 'hermes-engine' - pod 'libevent', :podspec => "#{prefix}/third-party-podspecs/libevent.podspec" + pod 'libevent', '~> 2.1.12' end end def use_flipper!(versions = {}, configurations: ['Debug']) - versions['Flipper'] ||= '~> 0.54.0' + versions['Flipper'] ||= '~> 0.75.1' versions['Flipper-DoubleConversion'] ||= '1.1.7' - versions['Flipper-Folly'] ||= '~> 2.2' + versions['Flipper-Folly'] ||= '~> 2.5' versions['Flipper-Glog'] ||= '0.3.6' versions['Flipper-PeerTalk'] ||= '~> 0.0.4' - versions['Flipper-RSocket'] ||= '~> 1.1' + versions['Flipper-RSocket'] ||= '~> 1.3' pod 'FlipperKit', versions['Flipper'], :configurations => configurations pod 'FlipperKit/FlipperKitLayoutPlugin', versions['Flipper'], :configurations => configurations pod 'FlipperKit/SKIOSNetworkPlugin', versions['Flipper'], :configurations => configurations diff --git a/template/android/gradle.properties b/template/android/gradle.properties index 3bdbd3d4e90ec3..d21d03f2b414a0 100644 --- a/template/android/gradle.properties +++ b/template/android/gradle.properties @@ -25,4 +25,4 @@ android.useAndroidX=true android.enableJetifier=true # Version of flipper SDK to use with React Native -FLIPPER_VERSION=0.54.0 +FLIPPER_VERSION=0.75.1 diff --git a/third-party-podspecs/libevent.podspec b/third-party-podspecs/libevent.podspec deleted file mode 100644 index b4274e38346c2f..00000000000000 --- a/third-party-podspecs/libevent.podspec +++ /dev/null @@ -1,565 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -# Because libevent is also relied on by Flipper and *with* OpenSSL bindings, -# building it as a prebuilt binary may lead to hard to satisfy permutations, if -# we'd ever try to build this for other Apple platforms besides macOS. Therefore -# let Xcode build it from source instead. -# -# Generated with: -# -# $ mkdir build && cd build -# $ cmake -G Ninja .. \ -# -DEVENT__DISABLE_OPENSSL:BOOL=ON \ -# -DEVENT__DISABLE_BENCHMARK:BOOL=ON \ -# -DEVENT__DISABLE_TESTS:BOOL=ON \ -# -DEVENT__DISABLE_REGRESS:BOOL=ON \ -# -DEVENT__DISABLE_SAMPLES:BOOL=ON -# $ cat include/event2/event-config.h -# -CONFIG_WITHOUT_OPENSSL = <<-END_OF_CONFIG -/* event-config.h - * - * This file was generated by cmake when the makefiles were generated. - * - * DO NOT EDIT THIS FILE. - * - * Do not rely on macros in this file existing in later versions. - */ -#ifndef EVENT2_EVENT_CONFIG_H_INCLUDED_ -#define EVENT2_EVENT_CONFIG_H_INCLUDED_ - -/* Numeric representation of the version */ -#define EVENT__NUMERIC_VERSION 0x02020001 -#define EVENT__PACKAGE_VERSION "2.2.0" - -#define EVENT__VERSION_MAJOR 2 -#define EVENT__VERSION_MINOR 2 -#define EVENT__VERSION_PATCH 0 - -/* Version number of package */ -#define EVENT__VERSION "2.2.0-alpha-dev" - -/* Name of package */ -#define EVENT__PACKAGE "libevent" - -/* Define to the address where bug reports for this package should be sent. */ -#define EVENT__PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define EVENT__PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define EVENT__PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define EVENT__PACKAGE_TARNAME "" - -/* Define if libevent should build without support for a debug mode */ -/* #undef EVENT__DISABLE_DEBUG_MODE */ - -/* Define if libevent should not allow replacing the mm functions */ -/* #undef EVENT__DISABLE_MM_REPLACEMENT */ - -/* Define if libevent should not be compiled with thread support */ -/* #undef EVENT__DISABLE_THREAD_SUPPORT */ - -/* Define to 1 if you have the `accept4' function. */ -/* #undef EVENT__HAVE_ACCEPT4 */ - -/* Define to 1 if you have the `arc4random' function. */ -#define EVENT__HAVE_ARC4RANDOM 1 - -/* Define to 1 if you have the `arc4random_buf' function. */ -#define EVENT__HAVE_ARC4RANDOM_BUF 1 - -/* Define to 1 if you have the `arc4random_addrandom' function. */ -#define EVENT__HAVE_ARC4RANDOM_ADDRANDOM 1 - -/* Define if clock_gettime is available in libc */ -#define EVENT__DNS_USE_CPU_CLOCK_FOR_ID 1 - -/* Define is no secure id variant is available */ -/* #undef EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID */ -/* #undef EVENT__DNS_USE_FTIME_FOR_ID */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_ARPA_INET_H 1 - -/* Define to 1 if you have the `clock_gettime' function. */ -#define EVENT__HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the declaration of `CTL_KERN'. */ -#define EVENT__HAVE_DECL_CTL_KERN 1 - -/* Define to 1 if you have the declaration of `KERN_ARND'. */ -#define EVENT__HAVE_DECL_KERN_ARND 0 - -/* Define to 1 if you have `getrandom' function. */ -/* #undef EVENT__HAVE_GETRANDOM */ - -/* Define if /dev/poll is available */ -/* #undef EVENT__HAVE_DEVPOLL */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_NETDB_H 1 - -/* Define to 1 if fd_mask type is defined */ -#define EVENT__HAVE_FD_MASK 1 - -/* Define to 1 if the header file defines TAILQ_FOREACH. */ -#define EVENT__HAVE_TAILQFOREACH 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_DLFCN_H 1 - -/* Define if your system supports the epoll system calls */ -/* #undef EVENT__HAVE_EPOLL */ - -/* Define to 1 if you have the `epoll_create1' function. */ -/* #undef EVENT__HAVE_EPOLL_CREATE1 */ - -/* Define to 1 if you have the `epoll_ctl' function. */ -/* #undef EVENT__HAVE_EPOLL_CTL */ - -/* Define if your system supports the wepoll module */ -/* #undef EVENT__HAVE_WEPOLL */ - -/* Define to 1 if you have the `eventfd' function. */ -/* #undef EVENT__HAVE_EVENTFD */ - -/* Define if your system supports event ports */ -/* #undef EVENT__HAVE_EVENT_PORTS */ - -/* Define to 1 if you have the `fcntl' function. */ -#define EVENT__HAVE_FCNTL 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `getaddrinfo' function. */ -#define EVENT__HAVE_GETADDRINFO 1 - -/* Define to 1 if you have the `getegid' function. */ -#define EVENT__HAVE_GETEGID 1 - -/* Define to 1 if you have the `geteuid' function. */ -#define EVENT__HAVE_GETEUID 1 - -/* TODO: Check for different gethostname argument counts. CheckPrototypeDefinition.cmake can be used. */ -/* Define this if you have any gethostbyname_r() */ -/* #undef EVENT__HAVE_GETHOSTBYNAME_R */ - -/* Define this if gethostbyname_r takes 3 arguments */ -/* #undef EVENT__HAVE_GETHOSTBYNAME_R_3_ARG */ - -/* Define this if gethostbyname_r takes 5 arguments */ -/* #undef EVENT__HAVE_GETHOSTBYNAME_R_5_ARG */ - -/* Define this if gethostbyname_r takes 6 arguments */ -/* #undef EVENT__HAVE_GETHOSTBYNAME_R_6_ARG */ - -/* Define to 1 if you have the `getifaddrs' function. */ -#define EVENT__HAVE_GETIFADDRS 1 - -/* Define to 1 if you have the `getnameinfo' function. */ -#define EVENT__HAVE_GETNAMEINFO 1 - -/* Define to 1 if you have the `getprotobynumber' function. */ -#define EVENT__HAVE_GETPROTOBYNUMBER 1 - -/* Define to 1 if you have the `getservbyname' function. */ -#define EVENT__HAVE_GETSERVBYNAME 1 - -/* Define to 1 if you have the `gettimeofday' function. */ -#define EVENT__HAVE_GETTIMEOFDAY 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_IFADDRS_H 1 - -/* Define to 1 if you have the `inet_ntop' function. */ -#define EVENT__HAVE_INET_NTOP 1 - -/* Define to 1 if you have the `inet_pton' function. */ -#define EVENT__HAVE_INET_PTON 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `issetugid' function. */ -#define EVENT__HAVE_ISSETUGID 1 - -/* Define to 1 if you have the `kqueue' function. */ -#define EVENT__HAVE_KQUEUE 1 - -/* Define if the system has zlib */ -/* #undef EVENT__HAVE_LIBZ */ - -/* Define to 1 if you have the `mach_absolute_time' function. */ -#define EVENT__HAVE_MACH_ABSOLUTE_TIME 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_MACH_MACH_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_MACH_MACH_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `mmap' function. */ -#define EVENT__HAVE_MMAP 1 - -/* Define to 1 if you have the `nanosleep' function. */ -#define EVENT__HAVE_NANOSLEEP 1 - -/* Define to 1 if you have the `usleep' function. */ -#define EVENT__HAVE_USLEEP 1 - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_NETINET_IN6_H */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_NETINET_IN_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_NETINET_TCP_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_UN_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_AFUNIX_H */ - -/* Define if the system has openssl */ -/* #undef EVENT__HAVE_OPENSSL */ - -/* Define to 1 if you have the `pipe' function. */ -#define EVENT__HAVE_PIPE 1 - -/* Define to 1 if you have the `pipe2' function. */ -/* #undef EVENT__HAVE_PIPE2 */ - -/* Define to 1 if you have the `poll' function. */ -#define EVENT__HAVE_POLL 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_POLL_H 1 - -/* Define to 1 if you have the `port_create' function. */ -/* #undef EVENT__HAVE_PORT_CREATE */ - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_PORT_H */ - -/* Define if we have pthreads on this system */ -#define EVENT__HAVE_PTHREADS 1 - -/* Define to 1 if you have the `putenv' function. */ -#define EVENT__HAVE_PUTENV 1 - -/* Define to 1 if the system has the type `sa_family_t'. */ -#define EVENT__HAVE_SA_FAMILY_T 1 - -/* Define to 1 if you have the `select' function. */ -#define EVENT__HAVE_SELECT 1 - -/* Define to 1 if you have the `setenv' function. */ -#define EVENT__HAVE_SETENV 1 - -/* Define if F_SETFD is defined in */ -#define EVENT__HAVE_SETFD 1 - -/* Define to 1 if you have the `setrlimit' function. */ -#define EVENT__HAVE_SETRLIMIT 1 - -/* Define to 1 if you have the `sendfile' function. */ -#define EVENT__HAVE_SENDFILE 1 - -/* Define to 1 if you have the `sigaction' function. */ -#define EVENT__HAVE_SIGACTION 1 - -/* Define to 1 if you have the `signal' function. */ -#define EVENT__HAVE_SIGNAL 1 - -/* Define to 1 if you have the `strsignal' function. */ -#define EVENT__HAVE_STRSIGNAL 1 - -/* Define to 1 if you have the `splice' function. */ -/* #undef EVENT__HAVE_SPLICE */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_STDARG_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_STDDEF_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_STRING_H 1 - -/* Define to 1 if you have the `strlcpy' function. */ -#define EVENT__HAVE_STRLCPY 1 - -/* Define to 1 if you have the `strsep' function. */ -#define EVENT__HAVE_STRSEP 1 - -/* Define to 1 if you have the `strtok_r' function. */ -#define EVENT__HAVE_STRTOK_R 1 - -/* Define to 1 if you have the `strtoll' function. */ -#define EVENT__HAVE_STRTOLL 1 - -/* Define to 1 if you have the `_gmtime64_s' function. */ -/* #undef EVENT__HAVE__GMTIME64_S */ - -/* Define to 1 if you have the `_gmtime64' function. */ -/* #undef EVENT__HAVE__GMTIME64 */ - -/* Define to 1 if the system has the type `struct addrinfo'. */ -#define EVENT__HAVE_STRUCT_ADDRINFO 1 - -/* Define to 1 if the system has the type `struct in6_addr'. */ -#define EVENT__HAVE_STRUCT_IN6_ADDR 1 - -/* Define to 1 if `s6_addr16' is member of `struct in6_addr'. */ -/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR16 */ - -/* Define to 1 if `s6_addr32' is member of `struct in6_addr'. */ -/* #undef EVENT__HAVE_STRUCT_IN6_ADDR_S6_ADDR32 */ - -/* Define to 1 if the system has the type `struct sockaddr_in6'. */ -#define EVENT__HAVE_STRUCT_SOCKADDR_IN6 1 - -/* Define to 1 if `sin6_len' is member of `struct sockaddr_in6'. */ -#define EVENT__HAVE_STRUCT_SOCKADDR_IN6_SIN6_LEN 1 - -/* Define to 1 if `sin_len' is member of `struct sockaddr_in'. */ -/* #undef EVENT__HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ - -/* Define to 1 if the system has the type `struct sockaddr_un'. */ -#define EVENT__HAVE_STRUCT_SOCKADDR_UN 1 - -/* Define to 1 if the system has the type `struct sockaddr_storage'. */ -#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE 1 - -/* Define to 1 if `ss_family' is a member of `struct sockaddr_storage'. */ -#define EVENT__HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 1 - -/* Define to 1 if `__ss_family' is a member of `struct sockaddr_storage'. */ -/* #undef EVENT__HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ - -/* Define to 1 if the system has the type `struct linger'. */ -#define EVENT__HAVE_STRUCT_LINGER 1 - -/* Define to 1 if you have the `sysctl' function. */ -#define EVENT__HAVE_SYSCTL 1 - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_SYS_EPOLL_H */ - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_SYS_EVENTFD_H */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_EVENT_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_IOCTL_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_MMAN_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_QUEUE_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_RESOURCE_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_SELECT_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_SYS_SENDFILE_H */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_SOCKET_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_RANDOM_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_SYSCTL_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef EVENT__HAVE_SYS_TIMERFD_H */ - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_UIO_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_SYS_WAIT_H 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_ERRNO_H 1 - -/* Define if TAILQ_FOREACH is defined in */ -#define EVENT__HAVE_TAILQFOREACH 1 - -/* Define if timeradd is defined in */ -#define EVENT__HAVE_TIMERADD 1 - -/* Define if timerclear is defined in */ -#define EVENT__HAVE_TIMERCLEAR 1 - -/* Define if timercmp is defined in */ -#define EVENT__HAVE_TIMERCMP 1 - - -/* Define to 1 if you have the `timerfd_create' function. */ -/* #undef EVENT__HAVE_TIMERFD_CREATE */ - -/* Define if timerisset is defined in */ -#define EVENT__HAVE_TIMERISSET 1 - -/* Define to 1 if the system has the type `uint8_t'. */ -#define EVENT__HAVE_UINT8_T 1 - -/* Define to 1 if the system has the type `uint16_t'. */ -#define EVENT__HAVE_UINT16_T 1 - -/* Define to 1 if the system has the type `uint32_t'. */ -#define EVENT__HAVE_UINT32_T 1 - -/* Define to 1 if the system has the type `uint64_t'. */ -#define EVENT__HAVE_UINT64_T 1 - -/* Define to 1 if the system has the type `uintptr_t'. */ -#define EVENT__HAVE_UINTPTR_T 1 - -/* Define to 1 if you have the `umask' function. */ -#define EVENT__HAVE_UMASK 1 - -/* Define to 1 if you have the header file. */ -#define EVENT__HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `unsetenv' function. */ -#define EVENT__HAVE_UNSETENV 1 - -/* Define to 1 if you have the `vasprintf' function. */ -#define EVENT__HAVE_VASPRINTF 1 - -/* Define if kqueue works correctly with pipes */ -#define EVENT__HAVE_WORKING_KQUEUE 1 - -#ifdef __USE_UNUSED_DEFINITIONS__ -/* Define to necessary symbol if this constant uses a non-standard name on your system. */ -/* XXX: Hello, this isn't even used, nor is it defined anywhere... - Ellzey */ -#define EVENT__PTHREAD_CREATE_JOINABLE -#endif - -/* The size of `pthread_t', as computed by sizeof. */ -#define EVENT__SIZEOF_PTHREAD_T 8 - -/* The size of a `int', as computed by sizeof. */ -#define EVENT__SIZEOF_INT 4 - -/* The size of a `long', as computed by sizeof. */ -#define EVENT__SIZEOF_LONG 8 - -/* The size of a `long long', as computed by sizeof. */ -#define EVENT__SIZEOF_LONG_LONG 8 - -/* The size of `off_t', as computed by sizeof. */ -#define EVENT__SIZEOF_OFF_T 8 - -#define EVENT__SIZEOF_SSIZE_T 8 - - -/* The size of a `short', as computed by sizeof. */ -#define EVENT__SIZEOF_SHORT 2 - -/* The size of `size_t', as computed by sizeof. */ -#define EVENT__SIZEOF_SIZE_T 8 - -/* Define to 1 if you can safely include both and . */ -/* #undef EVENT__TIME_WITH_SYS_TIME */ - -/* The size of `socklen_t', as computed by sizeof. */ -#define EVENT__SIZEOF_SOCKLEN_T 4 - -/* The size of 'void *', as computer by sizeof */ -#define EVENT__SIZEOF_VOID_P 8 - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* why not c++? - * - * and are we really expected to use EVENT__inline everywhere, - * shouldn't we just do: - * ifdef EVENT__inline - * define inline EVENT__inline - * - * - Ellzey - */ - -#define EVENT__inline inline -#endif - -#define EVENT__HAVE___func__ 1 -#define EVENT__HAVE___FUNCTION__ 1 - -/* Define to `unsigned' if does not define. */ -#define EVENT__size_t size_t - -/* Define to unsigned int if you dont have it */ -#define EVENT__socklen_t socklen_t - -/* Define to `int' if does not define. */ -#define EVENT__ssize_t ssize_t - -#endif /* \EVENT2_EVENT_CONFIG_H_INCLUDED_ */ -END_OF_CONFIG - -Pod::Spec.new do |spec| - spec.name = "libevent" - spec.version = "2.1.11" - spec.summary = "Event notification library" - spec.description = "The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts." - spec.homepage = "https://libevent.org" - spec.license = { :type => "BSD 3-Clause", :file => "LICENSE" } - spec.author = "Niels Provos and Nick Mathewson" - spec.platforms = { :osx => "10.13", :ios => "11.0" } - spec.source = { :git => "https://github.com/libevent/libevent.git", :tag => "release-#{spec.version}-stable" } - spec.prepare_command = "touch evconfig-private.h; echo -e #{Shellwords.escape(CONFIG_WITHOUT_OPENSSL)} > include/event2/event-config.h" - spec.source_files = - "include/*.h", "*-{internal,private}.h", - "buffer.c", "bufferevent.c", "bufferevent_filter.c", "bufferevent_pair.c", "bufferevent_ratelim.c", "bufferevent_sock.c", - "event.c", "evmap.c", "evthread.c", "evutil.c", "evutil_rand.c", "evutil_time.c", - "kqueue.c", "listener.c", "log.c", "poll.c", "select.c", "signal.c", "strlcpy.c", "watch.c", - "evdns.c", "event_tagging.c", "evrpc.c", "http.c" - spec.private_header_files = "*-{internal,private}.h" - spec.public_header_files = "include/*.h" - spec.preserve_paths = "include/event2/*.h" - spec.xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/include/\"" } -end From ac704690dcc9ef6ac8e4e855c8542b5fc708e4d3 Mon Sep 17 00:00:00 2001 From: Andrei Shikov Date: Wed, 24 Feb 2021 12:23:58 -0800 Subject: [PATCH 04/51] Update Android.mk to ensure the rn-tester compiles in debug mode Summary: Changelog: [Internal] Adds react_debug dependency in Android.mk where it was missing Reviewed By: mdvacca Differential Revision: D26617400 fbshipit-source-id: 5ac799269b106eadd881d30490ac34bd2134a9b7 --- .../java/com/facebook/react/fabric/jni/Android.mk | 3 ++- ReactCommon/react/debug/Android.mk | 2 ++ ReactCommon/react/renderer/animations/Android.mk | 3 ++- .../react/renderer/attributedstring/Android.mk | 3 ++- .../react/renderer/componentregistry/Android.mk | 3 ++- .../react/renderer/components/image/Android.mk | 3 ++- .../react/renderer/components/picker/Android.mk | 2 +- .../react/renderer/components/progressbar/Android.mk | 2 +- .../react/renderer/components/root/Android.mk | 3 ++- .../react/renderer/components/scrollview/Android.mk | 3 ++- .../react/renderer/components/slider/Android.mk | 2 +- .../react/renderer/components/switch/Android.mk | 2 +- .../react/renderer/components/text/Android.mk | 3 ++- .../react/renderer/components/textinput/Android.mk | 3 ++- .../renderer/components/unimplementedview/Android.mk | 3 ++- .../react/renderer/components/view/Android.mk | 3 ++- ReactCommon/react/renderer/core/Android.mk | 3 ++- ReactCommon/react/renderer/graphics/Android.mk | 3 ++- ReactCommon/react/renderer/imagemanager/Android.mk | 3 ++- ReactCommon/react/renderer/mounting/Android.mk | 3 ++- ReactCommon/react/renderer/scheduler/Android.mk | 3 ++- ReactCommon/react/renderer/uimanager/Android.mk | 3 ++- .../src/generators/modules/GenerateModuleJniH.js | 2 +- .../__snapshots__/GenerateModuleJniH-test.js.snap | 12 ++++++------ 24 files changed, 47 insertions(+), 28 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk index e63fd782d4d7b1..a20d60caf044f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := fabricjni LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) -LOCAL_SHARED_LIBRARIES := libreactconfig librrc_slider librrc_progressbar librrc_switch librrc_modal libyoga libglog libfb libfbjni libglog_init libfolly_json libfolly_futures libreact_render_mounting libreactnativeutilsjni libreact_utils libreact_render_debug libreact_render_graphics libreact_render_core libreact_render_mapbuffer react_render_componentregistry librrc_view librrc_unimplementedview librrc_root librrc_scrollview libbetter libreact_render_attributedstring libreact_render_uimanager libreact_render_templateprocessor libreact_render_scheduler libreact_render_animations libreact_render_imagemanager libreact_render_textlayoutmanager libreact_codegen_rncore rrc_text librrc_image rrc_textinput rrc_picker +LOCAL_SHARED_LIBRARIES := libreactconfig librrc_slider librrc_progressbar librrc_switch librrc_modal libyoga libglog libfb libfbjni libglog_init libfolly_json libfolly_futures libreact_render_mounting libreactnativeutilsjni libreact_utils libreact_render_debug libreact_render_graphics libreact_render_core libreact_render_mapbuffer react_render_componentregistry librrc_view librrc_unimplementedview librrc_root librrc_scrollview libbetter libreact_render_attributedstring libreact_render_uimanager libreact_render_templateprocessor libreact_render_scheduler libreact_render_animations libreact_render_imagemanager libreact_render_textlayoutmanager libreact_codegen_rncore rrc_text librrc_image librrc_textinput librrc_picker libreact_debug LOCAL_STATIC_LIBRARIES := @@ -34,6 +34,7 @@ $(call import-module,yogajni) $(call import-module,glog) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,react/config) $(call import-module,react/renderer/animations) $(call import-module,react/renderer/attributedstring) diff --git a/ReactCommon/react/debug/Android.mk b/ReactCommon/react/debug/Android.mk index fed711337bf390..14bb49bdc87259 100644 --- a/ReactCommon/react/debug/Android.mk +++ b/ReactCommon/react/debug/Android.mk @@ -17,6 +17,8 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../ LOCAL_SHARED_LIBRARIES := libfolly_json +LOCAL_LDLIBS := -llog + LOCAL_CFLAGS := \ -DLOG_TAG=\"Fabric\" diff --git a/ReactCommon/react/renderer/animations/Android.mk b/ReactCommon/react/renderer/animations/Android.mk index da7c4531e0b6bd..0f0e3cc0f07576 100644 --- a/ReactCommon/react/renderer/animations/Android.mk +++ b/ReactCommon/react/renderer/animations/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libreact_render_graphics libglog_init glog libruntimeexecutor libyoga librrc_view libreact_render_uimanager libfolly_futures libreact_render_componentregistry libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug libreact_render_mounting +LOCAL_SHARED_LIBRARIES := libreact_render_graphics libglog_init glog libruntimeexecutor libyoga librrc_view libreact_render_uimanager libfolly_futures libreact_render_componentregistry libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug libreact_render_mounting libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -39,3 +39,4 @@ $(call import-module,react/renderer/mounting) $(call import-module,react/renderer/uimanager) $(call import-module,yogajni) $(call import-module,runtimeexecutor) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/attributedstring/Android.mk b/ReactCommon/react/renderer/attributedstring/Android.mk index a9cfe21f7f01d0..2b90b0378380cb 100644 --- a/ReactCommon/react/renderer/attributedstring/Android.mk +++ b/ReactCommon/react/renderer/attributedstring/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libbetter libreact_render_graphics libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug librrc_view libreact_utils +LOCAL_SHARED_LIBRARIES := libbetter libreact_render_graphics libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug librrc_view libreact_utils libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -35,4 +35,5 @@ $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/componentregistry/Android.mk b/ReactCommon/react/renderer/componentregistry/Android.mk index 3ca9726aa4d927..5483a322716da3 100644 --- a/ReactCommon/react/renderer/componentregistry/Android.mk +++ b/ReactCommon/react/renderer/componentregistry/Android.mk @@ -15,7 +15,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../ -LOCAL_SHARED_LIBRARIES := libjsi libfolly_futures libfolly_json libreact_render_core libreact_render_debug libreact_utils libglog_init +LOCAL_SHARED_LIBRARIES := libjsi libfolly_futures libfolly_json libreact_render_core libreact_render_debug libreact_utils libglog_init libreact_debug LOCAL_CFLAGS := \ -DLOG_TAG=\"Fabric\" @@ -30,3 +30,4 @@ $(call import-module,jsi) $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/utils) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/components/image/Android.mk b/ReactCommon/react/renderer/components/image/Android.mk index f1b4276e50f675..eeaa35d4e74ae6 100644 --- a/ReactCommon/react/renderer/components/image/Android.mk +++ b/ReactCommon/react/renderer/components/image/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_render_imagemanager +LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_render_imagemanager libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -34,3 +34,4 @@ $(call import-module,react/renderer/graphics) $(call import-module,react/renderer/imagemanager) $(call import-module,react/renderer/components/view) $(call import-module,yogajni) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/components/picker/Android.mk b/ReactCommon/react/renderer/components/picker/Android.mk index 44e77f7fd947dd..0aa9cce17b777b 100644 --- a/ReactCommon/react/renderer/components/picker/Android.mk +++ b/ReactCommon/react/renderer/components/picker/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_uimanager librrc_view libreact_render_componentregistry libreact_codegen_rncore +LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_uimanager librrc_view libreact_render_componentregistry libreact_codegen_rncore libreact_debug include $(BUILD_SHARED_LIBRARY) diff --git a/ReactCommon/react/renderer/components/progressbar/Android.mk b/ReactCommon/react/renderer/components/progressbar/Android.mk index 5bdcc3d147d4e9..6e0297990bdcff 100644 --- a/ReactCommon/react/renderer/components/progressbar/Android.mk +++ b/ReactCommon/react/renderer/components/progressbar/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) diff --git a/ReactCommon/react/renderer/components/root/Android.mk b/ReactCommon/react/renderer/components/root/Android.mk index ed7f2302b60fff..76de642727803e 100644 --- a/ReactCommon/react/renderer/components/root/Android.mk +++ b/ReactCommon/react/renderer/components/root/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -32,4 +32,5 @@ $(call import-module,react/renderer/components/view) $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/components/scrollview/Android.mk b/ReactCommon/react/renderer/components/scrollview/Android.mk index c935e080753022..8726fbea871b8c 100644 --- a/ReactCommon/react/renderer/components/scrollview/Android.mk +++ b/ReactCommon/react/renderer/components/scrollview/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -32,4 +32,5 @@ $(call import-module,react/renderer/components/view) $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/components/slider/Android.mk b/ReactCommon/react/renderer/components/slider/Android.mk index b77f1085462ba1..d64d8a9cb6dab4 100644 --- a/ReactCommon/react/renderer/components/slider/Android.mk +++ b/ReactCommon/react/renderer/components/slider/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreact_render_imagemanager libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager librrc_image libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreact_render_imagemanager libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager librrc_image libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) diff --git a/ReactCommon/react/renderer/components/switch/Android.mk b/ReactCommon/react/renderer/components/switch/Android.mk index 3f155056991974..1cba4aa39daf87 100644 --- a/ReactCommon/react/renderer/components/switch/Android.mk +++ b/ReactCommon/react/renderer/components/switch/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libfbjni libreact_codegen_rncore libreactnativeutilsjni libreact_render_componentregistry libreact_render_uimanager libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) diff --git a/ReactCommon/react/renderer/components/text/Android.mk b/ReactCommon/react/renderer/components/text/Android.mk index d1e0b37affd010..160867b6ac9067 100644 --- a/ReactCommon/react/renderer/components/text/Android.mk +++ b/ReactCommon/react/renderer/components/text/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_uimanager libreact_render_textlayoutmanager libreact_render_attributedstring libreact_render_mounting librrc_view libreact_utils +LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_uimanager libreact_render_textlayoutmanager libreact_render_attributedstring libreact_render_mounting librrc_view libreact_utils libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -37,4 +37,5 @@ $(call import-module,react/renderer/textlayoutmanager) $(call import-module,react/renderer/uimanager) $(call import-module,react/renderer/components/view) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/components/textinput/Android.mk b/ReactCommon/react/renderer/components/textinput/Android.mk index f04e39bab0dbb2..729aa7de908756 100644 --- a/ReactCommon/react/renderer/components/textinput/Android.mk +++ b/ReactCommon/react/renderer/components/textinput/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_mounting libreact_render_componentregistry libreact_render_debug libreact_render_graphics libreact_render_uimanager libreact_render_imagemanager libreact_render_textlayoutmanager libreact_render_attributedstring librrc_text librrc_image librrc_view libreact_utils +LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_mounting libreact_render_componentregistry libreact_render_debug libreact_render_graphics libreact_render_uimanager libreact_render_imagemanager libreact_render_textlayoutmanager libreact_render_attributedstring librrc_text librrc_image librrc_view libreact_utils libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -41,4 +41,5 @@ $(call import-module,react/renderer/components/image) $(call import-module,react/renderer/components/view) $(call import-module,react/renderer/components/text) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/components/unimplementedview/Android.mk b/ReactCommon/react/renderer/components/unimplementedview/Android.mk index 4495846594ace0..64e291b5fce9a4 100644 --- a/ReactCommon/react/renderer/components/unimplementedview/Android.mk +++ b/ReactCommon/react/renderer/components/unimplementedview/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view +LOCAL_SHARED_LIBRARIES := libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics librrc_view libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -33,3 +33,4 @@ $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) $(call import-module,yogajni) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/components/view/Android.mk b/ReactCommon/react/renderer/components/view/Android.mk index e8c7254d592996..de9148308c95e2 100644 --- a/ReactCommon/react/renderer/components/view/Android.mk +++ b/ReactCommon/react/renderer/components/view/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libyoga glog libfolly_json libglog_init libreact_render_core libreact_render_debug libreact_render_graphics libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -32,3 +32,4 @@ $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) $(call import-module,yogajni) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/core/Android.mk b/ReactCommon/react/renderer/core/Android.mk index 66912423b0514b..b6787cd9cd8d10 100644 --- a/ReactCommon/react/renderer/core/Android.mk +++ b/ReactCommon/react/renderer/core/Android.mk @@ -15,7 +15,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../ -LOCAL_SHARED_LIBRARIES := libfolly_json libjsi libfolly_futures libreact_utils libreact_render_debug libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libfolly_json libjsi libfolly_futures libreact_utils libreact_debug libreact_render_debug libreact_render_graphics LOCAL_CFLAGS := \ -DLOG_TAG=\"Fabric\" @@ -27,5 +27,6 @@ include $(BUILD_SHARED_LIBRARY) $(call import-module,folly) $(call import-module,jsi) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) diff --git a/ReactCommon/react/renderer/graphics/Android.mk b/ReactCommon/react/renderer/graphics/Android.mk index 675a27973a5f91..8ef8528ecb6a72 100644 --- a/ReactCommon/react/renderer/graphics/Android.mk +++ b/ReactCommon/react/renderer/graphics/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_render_graphics LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp $(LOCAL_PATH)/platform/cxx/react/renderer/graphics/*.cpp) -LOCAL_SHARED_LIBRARIES := libfolly_json +LOCAL_SHARED_LIBRARIES := libfolly_json libreact_debug LOCAL_STATIC_LIBRARIES := @@ -27,3 +27,4 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall include $(BUILD_SHARED_LIBRARY) $(call import-module,folly) +$(call import-module,react/debug) diff --git a/ReactCommon/react/renderer/imagemanager/Android.mk b/ReactCommon/react/renderer/imagemanager/Android.mk index 0eca0e748917b9..b9a73742cacb9b 100644 --- a/ReactCommon/react/renderer/imagemanager/Android.mk +++ b/ReactCommon/react/renderer/imagemanager/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_render_imagemanager LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp $(LOCAL_PATH)/platform/cxx/react/renderer/imagemanager/*.cpp) -LOCAL_SHARED_LIBRARIES := libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_mounting +LOCAL_SHARED_LIBRARIES := libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics libreact_render_mounting libreact_debug LOCAL_STATIC_LIBRARIES := @@ -32,4 +32,5 @@ $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) $(call import-module,react/renderer/mounting) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/mounting/Android.mk b/ReactCommon/react/renderer/mounting/Android.mk index 7992d10a977c53..672372269bb028 100644 --- a/ReactCommon/react/renderer/mounting/Android.mk +++ b/ReactCommon/react/renderer/mounting/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libbetter libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug librrc_view librrc_root libreact_utils +LOCAL_SHARED_LIBRARIES := libbetter libyoga libfolly_futures glog libfolly_json libglog_init libreact_render_core libreact_render_debug librrc_view librrc_root libreact_utils libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -34,4 +34,5 @@ $(call import-module,react/renderer/components/view) $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/scheduler/Android.mk b/ReactCommon/react/renderer/scheduler/Android.mk index 992ac27f7edd9f..99f83fe362f806 100644 --- a/ReactCommon/react/renderer/scheduler/Android.mk +++ b/ReactCommon/react/renderer/scheduler/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libyoga librrc_view libreact_utils libreact_render_templateprocessor libreact_render_graphics libreact_render_uimanager libfolly_futures libreact_render_componentregistry glog libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug librrc_root libreact_render_mounting +LOCAL_SHARED_LIBRARIES := libyoga librrc_view libreact_utils libreact_render_templateprocessor libreact_render_graphics libreact_render_uimanager libfolly_futures libreact_render_componentregistry glog libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug librrc_root libreact_render_mounting libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -39,4 +39,5 @@ $(call import-module,react/renderer/mounting) $(call import-module,react/renderer/uimanager) $(call import-module,react/renderer/templateprocessor) $(call import-module,react/utils) +$(call import-module,react/debug) $(call import-module,yogajni) diff --git a/ReactCommon/react/renderer/uimanager/Android.mk b/ReactCommon/react/renderer/uimanager/Android.mk index 8ddd0e15831d61..95a4e53dd1d00e 100644 --- a/ReactCommon/react/renderer/uimanager/Android.mk +++ b/ReactCommon/react/renderer/uimanager/Android.mk @@ -21,7 +21,7 @@ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := libreact_render_graphics libfolly_futures libruntimeexecutor libreact_render_componentregistry glog libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug librrc_view librrc_root libreact_render_mounting +LOCAL_SHARED_LIBRARIES := libreact_render_graphics libfolly_futures libruntimeexecutor libreact_render_componentregistry glog libreactconfig libfolly_json libjsi libreact_render_core libreact_render_debug librrc_view librrc_root libreact_render_mounting libreact_debug include $(BUILD_SHARED_LIBRARY) @@ -36,4 +36,5 @@ $(call import-module,react/renderer/core) $(call import-module,react/renderer/debug) $(call import-module,react/renderer/graphics) $(call import-module,react/renderer/mounting) +$(call import-module,react/debug) $(call import-module,runtimeexecutor) diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js index bbce51534add61..7c98c6e7f7b56f 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleJniH.js @@ -80,7 +80,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/${libraryName} -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap index 8f1674fad58166..6bb1b8b9a9485f 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleJniH-test.js.snap @@ -52,7 +52,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/complex_objects -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi @@ -118,7 +118,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/empty_native_modules -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi @@ -184,7 +184,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/native_modules_with_type_aliases -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi @@ -258,7 +258,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/real_module_example -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi @@ -324,7 +324,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/simple_native_modules -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi @@ -398,7 +398,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) $(wildcard $(LOCAL_PATH)/reac LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/react/renderer/components/two_modules_different_files -LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libglog libfolly_json libyoga libreact_nativemodule_core librrc_view libreact_render_core libreact_render_graphics libreact_debug libreact_render_debug LOCAL_STATIC_LIBRARIES := libjsi From 3e06af93944a8b46e9f23fef55083ad6af6cb3c4 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Wed, 24 Feb 2021 16:34:42 -0800 Subject: [PATCH 05/51] Animated: Default to disabling view flattening for animated Views Summary: There's logic in Animated JS that prevents flattening of animated views in Fabric. However, we cannot actually detect Fabric vs non-Fabric in the first render pass; in the past we defaulted to assuming non-Fabric. Now we assume Fabric for View flattening purposes. Changelog: [Internal] Reviewed By: shergin Differential Revision: D26647393 fbshipit-source-id: c91b51aeeb4f352cc502bc018f086e36fd1ffd85 --- Libraries/Animated/createAnimatedComponent.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js index 8e8638edb63d58..988139fdd7fda3 100644 --- a/Libraries/Animated/createAnimatedComponent.js +++ b/Libraries/Animated/createAnimatedComponent.js @@ -87,6 +87,8 @@ function createAnimatedComponent( // When called during the first render, `_component` is always null. // Therefore, even if a component is rendered in Fabric, we can't detect // that until ref is set, which happens sometime after the first render. + // In cases where this value switching between "false" and "true" on Fabric + // causes issues, add an additional check for _component nullity. if (this._component == null) { return false; } @@ -221,10 +223,24 @@ function createAnimatedComponent( const {style: passthruStyle = {}, ...passthruProps} = this.props.passthroughAnimatedPropExplicitValues || {}; const mergedStyle = {...style, ...passthruStyle}; + + // On Fabric, we always want to ensure the container Animated View is *not* + // flattened. + // Because we do not get a host component ref immediately and thus cannot + // do a proper Fabric vs non-Fabric detection immediately, we default to assuming + // that Fabric *is* enabled until we know otherwise. + // Thus, in Fabric, this view will never be flattened. In non-Fabric, the view will + // not be flattened during the initial render but may be flattened in the second render + // and onwards. + const forceNativeIdFabric = + (this._component == null && + (options?.collapsable === false || props.collapsable !== true)) || + this._isFabric(); + const forceNativeId = props.collapsable ?? (this._propsAnimated.__isNative || - this._isFabric() || + forceNativeIdFabric || options?.collapsable === false); // The native driver updates views directly through the UI thread so we // have to make sure the view doesn't get optimized away because it cannot From 468bc62da33d65fc3a64db834c5e57cdf5f1d993 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Wed, 24 Feb 2021 17:12:58 -0800 Subject: [PATCH 06/51] Animated JS: clear out component refs on unmount Summary: "The instance should not stick around after unmount..." - Tim Yung, 2021 I have a hypothesis that, if a component instance of an animated component sticks around after unmount, it could cause memory leaks due to references to Fabric ShadowNodes across the JSI (this would not impact non-Fabric... in theory). Wild guess. If OOMs disappear then maybe this hypothesis is correct, but it's a long shot. I figure there's ~no harm in doing this cleanup here anyway. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D26650348 fbshipit-source-id: 90633db650b65755cacfb52344e7b53e46c9b125 --- Libraries/Animated/createAnimatedComponent.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Libraries/Animated/createAnimatedComponent.js b/Libraries/Animated/createAnimatedComponent.js index 988139fdd7fda3..fda18f0af80744 100644 --- a/Libraries/Animated/createAnimatedComponent.js +++ b/Libraries/Animated/createAnimatedComponent.js @@ -299,6 +299,8 @@ function createAnimatedComponent( this._propsAnimated && this._propsAnimated.__detach(); this._detachNativeEvents(); this._markUpdateComplete(); + this._component = null; + this._prevComponent = null; } } From eeb36f470929c2fdd8e1ed69898a5ba9144b8715 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rub=C3=A9n=20Norte?= Date: Thu, 25 Feb 2021 02:58:34 -0800 Subject: [PATCH 07/51] Improve display names of root components in React Profiler Summary: Changelog: [General][Added] - Added `debugName` parameter to `renderApplication` to use as the display name for the React root tree Reviewed By: rickhanlonii Differential Revision: D26637787 fbshipit-source-id: 3ddc037573f4434101a9d3dcb5592a127193481c --- Libraries/ReactNative/AppRegistry.js | 1 + Libraries/ReactNative/renderApplication.js | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Libraries/ReactNative/AppRegistry.js b/Libraries/ReactNative/AppRegistry.js index c08d003ac054bb..894d6a291a9c11 100644 --- a/Libraries/ReactNative/AppRegistry.js +++ b/Libraries/ReactNative/AppRegistry.js @@ -124,6 +124,7 @@ const AppRegistry = { showArchitectureIndicator, scopedPerformanceLogger, appKey === 'LogBox', + appKey, ); }, }; diff --git a/Libraries/ReactNative/renderApplication.js b/Libraries/ReactNative/renderApplication.js index 747b8ac36f251c..870b1e28968bf0 100644 --- a/Libraries/ReactNative/renderApplication.js +++ b/Libraries/ReactNative/renderApplication.js @@ -28,12 +28,13 @@ function renderApplication( showArchitectureIndicator?: boolean, scopedPerformanceLogger?: IPerformanceLogger, isLogBox?: boolean, + debugName?: string, ) { invariant(rootTag, 'Expect to have a valid rootTag, instead got ', rootTag); const performanceLogger = scopedPerformanceLogger ?? GlobalPerformanceLogger; - const renderable = ( + let renderable = ( ( ); + if (__DEV__ && debugName) { + const RootComponentWithMeaningfulName = ({children}) => children; + RootComponentWithMeaningfulName.displayName = `${debugName}(RootComponent)`; + renderable = ( + + {renderable} + + ); + } + performanceLogger.startTimespan('renderApplication_React_render'); performanceLogger.setExtra('usedReactFabric', fabric ? '1' : '0'); From 4e243ca7a34bf0ecc0b6169b7388f1aa00b66971 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Thu, 25 Feb 2021 10:06:56 -0800 Subject: [PATCH 08/51] Fix RTL scrolling Summary: We recently fixed RTL scrolling in Fabric on iOS: D26608231 (https://github.com/facebook/react-native/commit/e5921f7f384af45df4f355fa3fa1b58a20a269d3) Turns out, the mechanism for RTL scrolling on Android is completely different. It requires that content be wrapped in a "directional content view", which is `View` in LTR and `AndroidHorizontalScrollContentView` in RTL, backed by `ReactHorizontalScrollContainerView.java`. iOS doesn't require that and just uses View and some custom logic in ScrollView itself. In the future it would be great to align the platforms, but for now, for backwards-compat with non-Fabric and so we don't have to tear apart ScrollView.js, we codegen the AndroidHorizontalScrollContentView so it exists in C++, register the component, and stop mapping it to View explicitly in C++. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D26659686 fbshipit-source-id: 3b9c646dbdb7fe9527d24d42bdc6acb1aca00945 --- ...izontalScrollContentViewNativeComponent.js | 26 +++++++++---------- .../fabric/jni/CoreComponentsRegistry.cpp | 3 +++ .../ComponentDescriptorRegistry.cpp | 7 +++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Libraries/Components/ScrollView/AndroidHorizontalScrollContentViewNativeComponent.js b/Libraries/Components/ScrollView/AndroidHorizontalScrollContentViewNativeComponent.js index 4c542bddfacc9e..71210f989d7e20 100644 --- a/Libraries/Components/ScrollView/AndroidHorizontalScrollContentViewNativeComponent.js +++ b/Libraries/Components/ScrollView/AndroidHorizontalScrollContentViewNativeComponent.js @@ -4,22 +4,20 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @flow strict-local * @format + * @flow strict-local */ -import {type HostComponent} from '../../Renderer/shims/ReactNativeTypes'; -import * as NativeComponentRegistry from '../../NativeComponent/NativeComponentRegistry'; -import {type ViewProps as Props} from '../View/ViewPropTypes'; +import codegenNativeComponent from '../../Utilities/codegenNativeComponent'; +import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes'; +import type {ViewProps} from '../View/ViewPropTypes'; -const AndroidHorizontalScrollContentViewNativeComponent: HostComponent = NativeComponentRegistry.get( - 'AndroidHorizontalScrollContentView', - () => ({ - uiViewClassName: 'AndroidHorizontalScrollContentView', - bubblingEventTypes: {}, - directEventTypes: {}, - validAttributes: {}, - }), -); +type NativeProps = $ReadOnly<{| + ...ViewProps, +|}>; -export default AndroidHorizontalScrollContentViewNativeComponent; +type NativeType = HostComponent; + +export default (codegenNativeComponent( + 'AndroidHorizontalScrollContentView', +): NativeType); diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp index 560b8eaaa70fb2..cd13e075b17c1d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/CoreComponentsRegistry.cpp @@ -64,6 +64,9 @@ CoreComponentsRegistry::sharedProviderRegistry() { concreteComponentDescriptorProvider()); providerRegistry->add( concreteComponentDescriptorProvider()); + providerRegistry->add( + concreteComponentDescriptorProvider< + AndroidHorizontalScrollContentViewComponentDescriptor>()); providerRegistry->add( concreteComponentDescriptorProvider()); providerRegistry->add(concreteComponentDescriptorProvider< diff --git a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp index cb149393dde838..27cb851b102c7c 100644 --- a/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp +++ b/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.cpp @@ -68,7 +68,7 @@ static std::string componentNameByReactViewName(std::string viewName) { } // TODO T63839307: remove this condition after deleting TextInlineImage from - // Paper + // non-Fabric code if (viewName == "TextInlineImage") { return "Image"; } @@ -94,9 +94,8 @@ static std::string componentNameByReactViewName(std::string viewName) { // We need this temporarily for testing purposes until we have proper // implementation of core components. - if (viewName == "ScrollContentView" || - viewName == "AndroidHorizontalScrollContentView" // Android - ) { + // iOS-only + if (viewName == "ScrollContentView") { return "View"; } From f8261bbe512019398d4ccd2a18b8ff9dd030739d Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Thu, 25 Feb 2021 10:06:56 -0800 Subject: [PATCH 09/51] Don't pass LayoutDirection from Cxx to IntBufferBatchMountItem Summary: I thought we'd need LayoutDirection on the platform at some point, but it turns out we never use it, and don't seem to need it since components just query via `I18nUtil` one time, and it's expected that apps restart if language changes and we need to switch between LTR and RTL. So, it seems like we'll not have any need for this on the platform at any point. And we can save a byte per layout instruction now. Huzzah! Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26660908 fbshipit-source-id: 54c7d132f5fa260a93fc7f09f7cf63059d52ed1f --- .../java/com/facebook/react/fabric/jni/Binding.cpp | 11 ++++------- .../mounting/mountitems/IntBufferBatchMountItem.java | 5 +---- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp index 9e367641098980..afa2ede1e094d1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/Binding.cpp @@ -105,7 +105,7 @@ static inline int getIntBufferSizeForType(CppMountItem::Type mountItemType) { } else if (mountItemType == CppMountItem::Type::UpdatePadding) { return 5; // tag, top, left, bottom, right } else if (mountItemType == CppMountItem::Type::UpdateLayout) { - return 7; // tag, x, y, w, h, layoutDirection, DisplayType + return 6; // tag, x, y, w, h, DisplayType } else if (mountItemType == CppMountItem::Type::UpdateEventEmitter) { return 1; // tag } else { @@ -958,8 +958,6 @@ void Binding::schedulerDidFinishTransaction( int y = round(scale(frame.origin.y, pointScaleFactor)); int w = round(scale(frame.size.width, pointScaleFactor)); int h = round(scale(frame.size.height, pointScaleFactor)); - int layoutDirection = - toInt(mountItem.newChildShadowView.layoutMetrics.layoutDirection); int displayType = toInt(mountItem.newChildShadowView.layoutMetrics.displayType); @@ -968,10 +966,9 @@ void Binding::schedulerDidFinishTransaction( temp[2] = y; temp[3] = w; temp[4] = h; - temp[5] = layoutDirection; - temp[6] = displayType; - env->SetIntArrayRegion(intBufferArray, intBufferPosition, 7, temp); - intBufferPosition += 7; + temp[5] = displayType; + env->SetIntArrayRegion(intBufferArray, intBufferPosition, 6, temp); + intBufferPosition += 6; } } if (cppUpdateEventEmitterMountItems.size() > 0) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java index 311a08143ea3be..d6d3a0f9c2b4e5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/IntBufferBatchMountItem.java @@ -161,8 +161,6 @@ public void execute(@NonNull MountingManager mountingManager) { int y = mIntBuffer[i++]; int width = mIntBuffer[i++]; int height = mIntBuffer[i++]; - // The final buffer, layoutDirection, seems unused? - i++; int displayType = mIntBuffer[i++]; surfaceMountingManager.updateLayout(reactTag, x, y, width, height, displayType); @@ -232,8 +230,7 @@ public String toString() { } else if (type == INSTRUCTION_UPDATE_LAYOUT) { s.append( String.format( - "UPDATE LAYOUT [%d]: x:%d y:%d w:%d h:%d layoutDirection:%d displayType:%d\n", - mIntBuffer[i++], + "UPDATE LAYOUT [%d]: x:%d y:%d w:%d h:%d displayType:%d\n", mIntBuffer[i++], mIntBuffer[i++], mIntBuffer[i++], From 7b814b467a5571655dc4415080b3c9fcf5fd929e Mon Sep 17 00:00:00 2001 From: Stiopa Koltsov Date: Thu, 25 Feb 2021 15:25:42 -0800 Subject: [PATCH 10/51] xplat/js/react-native-github: Starlark compat Summary: There's no `set` in Starlark. Changelog: [Internal] Reviewed By: aniketmathur Differential Revision: D26665530 fbshipit-source-id: 1e67571b6a02601997d3f11a9d9c6776b8e1ff3b --- tools/build_defs/oss/rn_defs.bzl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/build_defs/oss/rn_defs.bzl b/tools/build_defs/oss/rn_defs.bzl index 64dc9b88ef64ca..515f938b239beb 100644 --- a/tools/build_defs/oss/rn_defs.bzl +++ b/tools/build_defs/oss/rn_defs.bzl @@ -126,6 +126,9 @@ def react_native_xplat_dep(path): def rn_extra_build_flags(): return [] +def _unique(li): + return list({x: () for x in li}) + # React property preprocessor def rn_android_library(name, deps = [], plugins = [], *args, **kwargs): _ = kwargs.pop("autoglob", False) @@ -139,7 +142,7 @@ def rn_android_library(name, deps = [], plugins = [], *args, **kwargs): ), ] - plugins = list(set(plugins + react_property_plugins)) + plugins = _unique(plugins + react_property_plugins) if react_native_target( "java/com/facebook/react/module/annotations:annotations", @@ -150,7 +153,7 @@ def rn_android_library(name, deps = [], plugins = [], *args, **kwargs): ), ] - plugins = list(set(plugins + react_module_plugins)) + plugins = _unique(plugins + react_module_plugins) native.android_library(name = name, deps = deps, plugins = plugins, *args, **kwargs) From b3cdf8cd7ecaf264f1eff2eae8050722d63ef15b Mon Sep 17 00:00:00 2001 From: David Vacca Date: Thu, 25 Feb 2021 17:54:49 -0800 Subject: [PATCH 11/51] Fix incorrect Height in Text components Summary: This diff fixes a bug in the calculation of layout for text components The rootcause of the bug is that fabric is not taking into consideration height constraints as part of the cache for text measurments. The title text was being measured with a specific height constraint (22px) at the begining of the render, later there was a re-measure for the same Text component with a different height constraint, but fabric was reusing the result of the first calculation instead of re-measuring the text. changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26676716 fbshipit-source-id: 3e769e0ca35b3e363b96d3a6d1626a091eaad908 --- .../react/renderer/textlayoutmanager/TextMeasureCache.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h index d0e71872810d75..823d106a3191d8 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h +++ b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h @@ -190,7 +190,9 @@ inline bool operator==( lhs.attributedString, rhs.attributedString) && lhs.paragraphAttributes == rhs.paragraphAttributes && lhs.layoutConstraints.maximumSize.width == - rhs.layoutConstraints.maximumSize.width; + rhs.layoutConstraints.maximumSize.width && + lhs.layoutConstraints.maximumSize.height == + rhs.layoutConstraints.maximumSize.height; } inline bool operator!=( From ab53332115a754a5c2144466c6fd56543a367829 Mon Sep 17 00:00:00 2001 From: Rick Hanlon Date: Thu, 25 Feb 2021 22:30:01 -0800 Subject: [PATCH 12/51] React Native sync for revisions c3e20f1...0cf9fc1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: This sync includes the following changes: - **[0cf9fc10b](https://github.com/facebook/react/commit/0cf9fc10b )**: Fix React Native flow types ([#20889](https://github.com/facebook/react/pull/20889)) //// - **[c581cdd48](https://github.com/facebook/react/commit/c581cdd48 )**: Schedule sync updates in microtask ([#20872](https://github.com/facebook/react/pull/20872)) //// - **[90bde6505](https://github.com/facebook/react/commit/90bde6505 )**: Add SuspenseList to react-is ([#20874](https://github.com/facebook/react/pull/20874)) //// - **[8336f19aa](https://github.com/facebook/react/commit/8336f19aa )**: Update React Native types ([#20883](https://github.com/facebook/react/pull/20883)) //// - **[9209c30ff](https://github.com/facebook/react/commit/9209c30ff )**: Add StrictMode level prop and createRoot unstable_strictModeLevel option ([#20849](https://github.com/facebook/react/pull/20849)) //// - **[e5f6b91d2](https://github.com/facebook/react/commit/e5f6b91d2 )**: Add Lane labels to scheduling profiler marks ([#20808](https://github.com/facebook/react/pull/20808)) //// - **[c62986cfd](https://github.com/facebook/react/commit/c62986cfd )**: Add additional messaging for RulesOfHooks lint error ([#20692](https://github.com/facebook/react/pull/20692)) //// - **[78d2f2d30](https://github.com/facebook/react/commit/78d2f2d30 )**: Fabric-compatible implementation of `JSReponder` feature ([#20768](https://github.com/facebook/react/pull/20768)) //// - **[4d28eca97](https://github.com/facebook/react/commit/4d28eca97 )**: Land enableNonInterruptingNormalPri ([#20859](https://github.com/facebook/react/pull/20859)) //// - **[8af27aeed](https://github.com/facebook/react/commit/8af27aeed )**: Remove scheduler sampling profiler shared array buffer ([#20840](https://github.com/facebook/react/pull/20840)) //// - **[af3d52611](https://github.com/facebook/react/commit/af3d52611 )**: Disable (unstable) scheduler sampling profiler for OSS builds ([#20832](https://github.com/facebook/react/pull/20832)) //// - **[8fa0ccca0](https://github.com/facebook/react/commit/8fa0ccca0 )**: fix: use SharedArrayBuffer only when cross-origin isolation is enabled ([#20831](https://github.com/facebook/react/pull/20831)) //// - **[099164792](https://github.com/facebook/react/commit/099164792 )**: Use setImmediate when available over MessageChannel ([#20834](https://github.com/facebook/react/pull/20834)) //// - **[e2fd460cc](https://github.com/facebook/react/commit/e2fd460cc )**: Bailout in sync task if work is not sync ([#20813](https://github.com/facebook/react/pull/20813)) //// - **[1a7472624](https://github.com/facebook/react/commit/1a7472624 )**: Add `supportsMicrotasks` to the host config ([#20809](https://github.com/facebook/react/pull/20809)) //// - **[696e736be](https://github.com/facebook/react/commit/696e736be )**: Warn if static flag is accidentally cleared ([#20807](https://github.com/facebook/react/pull/20807)) //// - **[483358c38](https://github.com/facebook/react/commit/483358c38 )**: Omit TransitionHydrationLane from TransitionLanes ([#20802](https://github.com/facebook/react/pull/20802)) //// - **[78ec97d34](https://github.com/facebook/react/commit/78ec97d34 )**: Fix typo ([#20466](https://github.com/facebook/react/pull/20466)) //// - **[6cdc35972](https://github.com/facebook/react/commit/6cdc35972 )**: fix comments of markUpdateLaneFromFiberToRoot ([#20546](https://github.com/facebook/react/pull/20546)) //// - **[47dd9f441](https://github.com/facebook/react/commit/47dd9f441 )**: Remove fakeCallbackNode ([#20799](https://github.com/facebook/react/pull/20799)) //// - **[114ab5295](https://github.com/facebook/react/commit/114ab5295 )**: Make remaining empty lanes Transition lanes ([#20793](https://github.com/facebook/react/pull/20793)) //// - **[d3d2451a0](https://github.com/facebook/react/commit/d3d2451a0 )**: Use a single lane per priority level ([#20791](https://github.com/facebook/react/pull/20791)) //// - **[eee874ce6](https://github.com/facebook/react/commit/eee874ce6 )**: Cross-fork lint: Support named export declaration ([#20784](https://github.com/facebook/react/pull/20784)) //// - **[3b870b1e0](https://github.com/facebook/react/commit/3b870b1e0 )**: Lane enableTransitionEntanglement flag ([#20775](https://github.com/facebook/react/pull/20775)) //// - **[d1845ad0f](https://github.com/facebook/react/commit/d1845ad0f )**: Default updates should not interrupt transitions ([#20771](https://github.com/facebook/react/pull/20771)) //// - **[3499c343a](https://github.com/facebook/react/commit/3499c343a )**: Apply #20778 to new fork, too ([#20782](https://github.com/facebook/react/pull/20782)) //// - **[3d10eca24](https://github.com/facebook/react/commit/3d10eca24 )**: Move scheduler priority check into ReactDOM ([#20778](https://github.com/facebook/react/pull/20778)) //// - **[97fce318a](https://github.com/facebook/react/commit/97fce318a )**: Experiment: Infer the current event priority from the native event ([#20748](https://github.com/facebook/react/pull/20748)) //// - **[6c526c515](https://github.com/facebook/react/commit/6c526c515 )**: Don't shift interleaved updates to separate lane ([#20681](https://github.com/facebook/react/pull/20681)) //// - **[35f7441d3](https://github.com/facebook/react/commit/35f7441d3 )**: Use Lanes instead of priority event constants ([#20762](https://github.com/facebook/react/pull/20762)) //// - **[a014c915c](https://github.com/facebook/react/commit/a014c915c )**: Parallel transitions: Assign different lanes to consecutive transitions ([#20672](https://github.com/facebook/react/pull/20672)) //// - **[77754ae61](https://github.com/facebook/react/commit/77754ae61 )**: Decouple event priority list from event name list ([#20760](https://github.com/facebook/react/pull/20760)) //// - **[b5bac1821](https://github.com/facebook/react/commit/b5bac1821 )**: Align event group constant naming with lane naming ([#20744](https://github.com/facebook/react/pull/20744)) //// - **[4ecf11977](https://github.com/facebook/react/commit/4ecf11977 )**: Remove the Fundamental internals ([#20745](https://github.com/facebook/react/pull/20745)) //// - **[eeb1325b0](https://github.com/facebook/react/commit/eeb1325b0 )**: Fix UMD bundles by removing usage of global ([#20743](https://github.com/facebook/react/pull/20743)) //// - **[0935a1db3](https://github.com/facebook/react/commit/0935a1db3 )**: Delete consolidateBundleSizes script ([#20724](https://github.com/facebook/react/pull/20724)) //// - **[7cb9fd7ef](https://github.com/facebook/react/commit/7cb9fd7ef )**: Land interleaved updates change in main fork ([#20710](https://github.com/facebook/react/pull/20710)) //// - **[dc27b5aaa](https://github.com/facebook/react/commit/dc27b5aaa )**: useMutableSource: Use StrictMode double render to detect render phase mutation ([#20698](https://github.com/facebook/react/pull/20698)) //// - **[bb1b7951d](https://github.com/facebook/react/commit/bb1b7951d )**: fix: don't run effects if a render phase update results in unchanged deps ([#20676](https://github.com/facebook/react/pull/20676)) //// - **[766a7a28a](https://github.com/facebook/react/commit/766a7a28a )**: Improve React error message when mutable sources are mutated during render ([#20665](https://github.com/facebook/react/pull/20665)) //// - **[a922f1c71](https://github.com/facebook/react/commit/a922f1c71 )**: Fix cache refresh bug that broke DevTools ([#20687](https://github.com/facebook/react/pull/20687)) //// - **[e51bd6c1f](https://github.com/facebook/react/commit/e51bd6c1f )**: Queue discrete events in microtask ([#20669](https://github.com/facebook/react/pull/20669)) //// - **[aa736a0fa](https://github.com/facebook/react/commit/aa736a0fa )**: Add queue microtask to host configs ([#20668](https://github.com/facebook/react/pull/20668)) //// - **[deeeaf1d2](https://github.com/facebook/react/commit/deeeaf1d2 )**: Entangle overlapping transitions per queue ([#20670](https://github.com/facebook/react/pull/20670)) //// - **[e316f7855](https://github.com/facebook/react/commit/e316f7855 )**: RN: Implement `sendAccessibilityEvent` in RN Renderer that proxies between Fabric/non-Fabric ([#20554](https://github.com/facebook/react/pull/20554)) //// - **[9c32622cf](https://github.com/facebook/react/commit/9c32622cf )**: Improve tests that use discrete events ([#20667](https://github.com/facebook/react/pull/20667)) //// - **[d13f5b953](https://github.com/facebook/react/commit/d13f5b953 )**: Experiment: Unsuspend all lanes on update ([#20660](https://github.com/facebook/react/pull/20660)) //// - **[a511dc709](https://github.com/facebook/react/commit/a511dc709 )**: Error for deferred value and transition in Server Components ([#20657](https://github.com/facebook/react/pull/20657)) //// - **[fb3f63f1a](https://github.com/facebook/react/commit/fb3f63f1a )**: Remove lazy invokation of segments ([#20656](https://github.com/facebook/react/pull/20656)) //// - **[895ae67fd](https://github.com/facebook/react/commit/895ae67fd )**: Improve error boundary handling for unmounted subtrees ([#20645](https://github.com/facebook/react/pull/20645)) //// - **[f15f8f64b](https://github.com/facebook/react/commit/f15f8f64b )**: Store interleaved updates on separate queue until end of render ([#20615](https://github.com/facebook/react/pull/20615)) //// - **[0fd6805c6](https://github.com/facebook/react/commit/0fd6805c6 )**: Land rest of effects refactor in main fork ([#20644](https://github.com/facebook/react/pull/20644)) //// - **[a6b5256a2](https://github.com/facebook/react/commit/a6b5256a2 )**: Refactored recursive strict effects method to be iterative ([#20642](https://github.com/facebook/react/pull/20642)) //// - **[3957853ae](https://github.com/facebook/react/commit/3957853ae )**: Re-add "strict effects mode" for legacy roots only ([#20639](https://github.com/facebook/react/pull/20639)) //// - **[fceb75e89](https://github.com/facebook/react/commit/fceb75e89 )**: Delete remaining references to effect list ([#20625](https://github.com/facebook/react/pull/20625)) //// - **[741dcbdbe](https://github.com/facebook/react/commit/741dcbdbe )**: Schedule passive phase whenever there's a deletion ([#20624](https://github.com/facebook/react/pull/20624)) //// - **[11a983fc7](https://github.com/facebook/react/commit/11a983fc7 )**: Remove references to Deletion flag ([#20623](https://github.com/facebook/react/pull/20623)) //// - **[2e948e0d9](https://github.com/facebook/react/commit/2e948e0d9 )**: Avoid .valueOf to close #20594 ([#20617](https://github.com/facebook/react/pull/20617)) //// - **[2a646f73e](https://github.com/facebook/react/commit/2a646f73e )**: Convert snapshot phase to depth-first traversal ([#20622](https://github.com/facebook/react/pull/20622)) //// - **[fb3e158a6](https://github.com/facebook/react/commit/fb3e158a6 )**: Convert ReactSuspenseWithNoopRenderer tests to use built-in cache ([#20601](https://github.com/facebook/react/pull/20601)) //// - **[e0fd9e67f](https://github.com/facebook/react/commit/e0fd9e67f )**: Use update lane priority in work loop ([#20621](https://github.com/facebook/react/pull/20621)) //// - **[58e830448](https://github.com/facebook/react/commit/58e830448 )**: Remove custom error message from hook access error ([#20604](https://github.com/facebook/react/pull/20604)) //// - **[9043626f0](https://github.com/facebook/react/commit/9043626f0 )**: Cache tests: Make it easier to test many caches ([#20600](https://github.com/facebook/react/pull/20600)) //// - **[af0bb68e8](https://github.com/facebook/react/commit/af0bb68e8 )**: Land #20595 and #20596 in main fork ([#20602](https://github.com/facebook/react/pull/20602)) //// - **[2b6985114](https://github.com/facebook/react/commit/2b6985114 )**: build-combined: Fix failures when renaming across devices ([#20620](https://github.com/facebook/react/pull/20620)) //// - **[af16f755d](https://github.com/facebook/react/commit/af16f755d )**: Update DevTools to use getCacheForType API ([#20548](https://github.com/facebook/react/pull/20548)) //// - **[95feb0e70](https://github.com/facebook/react/commit/95feb0e70 )**: Convert mutation phase to depth-first traversal ([#20596](https://github.com/facebook/react/pull/20596)) //// - **[6132919bf](https://github.com/facebook/react/commit/6132919bf )**: Convert layout phase to depth-first traversal ([#20595](https://github.com/facebook/react/pull/20595)) //// - **[42e04b46d](https://github.com/facebook/react/commit/42e04b46d )**: Fix: Detach deleted fiber's alternate, too ([#20587](https://github.com/facebook/react/pull/20587)) //// - **[a656ace8d](https://github.com/facebook/react/commit/a656ace8d )**: Deletion effects should fire parent -> child ([#20584](https://github.com/facebook/react/pull/20584)) //// - **[e6ed2bcf4](https://github.com/facebook/react/commit/e6ed2bcf4 )**: Update package.json versions as part of build step ([#20579](https://github.com/facebook/react/pull/20579)) //// - **[eb0fb3823](https://github.com/facebook/react/commit/eb0fb3823 )**: Build stable and experimental with same command ([#20573](https://github.com/facebook/react/pull/20573)) //// - **[e8eff119e](https://github.com/facebook/react/commit/e8eff119e )**: Fix ESLint crash on empty react effect hook ([#20385](https://github.com/facebook/react/pull/20385)) //// - **[27659559e](https://github.com/facebook/react/commit/27659559e )**: Add useRefresh hook to react-debug-tools ([#20460](https://github.com/facebook/react/pull/20460)) //// - **[99554dc36](https://github.com/facebook/react/commit/99554dc36 )**: Add Flight packages to experimental allowlist ([#20486](https://github.com/facebook/react/pull/20486)) //// - **[efc57e5cb](https://github.com/facebook/react/commit/efc57e5cb )**: Add built-in Suspense cache with support for invalidation (refreshing) ([#20456](https://github.com/facebook/react/pull/20456)) //// - **[00a5b08e2](https://github.com/facebook/react/commit/00a5b08e2 )**: Remove PassiveStatic optimization //// - **[a6329b105](https://github.com/facebook/react/commit/a6329b105 )**: Don't clear static flags in resetWorkInProgress //// - **[1cf59f34b](https://github.com/facebook/react/commit/1cf59f34b )**: Convert passive unmount phase to tree traversal //// - **[ab29695a0](https://github.com/facebook/react/commit/ab29695a0 )**: Defer more field detachments to passive phase //// - **[d37d7a4bb](https://github.com/facebook/react/commit/d37d7a4bb )**: Convert passive mount phase to tree traversal //// - **[19e15a398](https://github.com/facebook/react/commit/19e15a398 )**: Add PassiveStatic to trees with passive effects //// - **[ff17fc176](https://github.com/facebook/react/commit/ff17fc176 )**: Don't clear other flags when adding Deletion //// - **[5687864eb](https://github.com/facebook/react/commit/5687864eb )**: Add back disableSchedulerTimeoutInWorkLoop flag ([#20482](https://github.com/facebook/react/pull/20482)) //// - **[9f338e5d7](https://github.com/facebook/react/commit/9f338e5d7 )**: clone json obj in react native flight client host config parser ([#20474](https://github.com/facebook/react/pull/20474)) //// - **[4e62fd271](https://github.com/facebook/react/commit/4e62fd271 )**: clone json obj in relay flight client host config parser ([#20465](https://github.com/facebook/react/pull/20465)) //// - **[070372cde](https://github.com/facebook/react/commit/070372cde )**: [Flight] Fix webpack watch mode issue ([#20457](https://github.com/facebook/react/pull/20457)) //// - **[0f80dd148](https://github.com/facebook/react/commit/0f80dd148 )**: [Flight] Support concatenated modules in Webpack plugin ([#20449](https://github.com/facebook/react/pull/20449)) //// - **[daf38ecdf](https://github.com/facebook/react/commit/daf38ecdf )**: [Flight] Use lazy reference for existing modules ([#20445](https://github.com/facebook/react/pull/20445)) //// - **[3f9205c33](https://github.com/facebook/react/commit/3f9205c33 )**: Regression test: SuspenseList causes lost unmount ([#20433](https://github.com/facebook/react/pull/20433)) //// - **[cdfde3ae1](https://github.com/facebook/react/commit/cdfde3ae1 )**: Always rethrow original error when we replay errors ([#20425](https://github.com/facebook/react/pull/20425)) //// - **[b15d6e93e](https://github.com/facebook/react/commit/b15d6e93e )**: [Flight] Make PG and FS server-only ([#20424](https://github.com/facebook/react/pull/20424)) //// - **[40ff2395e](https://github.com/facebook/react/commit/40ff2395e )**: [Flight] Prevent non-Server imports of aliased Server entrypoints ([#20422](https://github.com/facebook/react/pull/20422)) //// - **[94aa365e3](https://github.com/facebook/react/commit/94aa365e3 )**: [Flight] Fix webpack plugin to use chunk groups ([#20421](https://github.com/facebook/react/pull/20421)) //// - **[842ee367e](https://github.com/facebook/react/commit/842ee367e )**: [Flight] Rename the shared entry point ([#20420](https://github.com/facebook/react/pull/20420)) //// - **[dbf40ef75](https://github.com/facebook/react/commit/dbf40ef75 )**: Put .server.js at the end of bundle filenames ([#20419](https://github.com/facebook/react/pull/20419)) //// - **[03126dd08](https://github.com/facebook/react/commit/03126dd08 )**: [Flight] Add read-only fs methods ([#20412](https://github.com/facebook/react/pull/20412)) //// - **[b51a686a9](https://github.com/facebook/react/commit/b51a686a9 )**: Turn on double effects for www test renderer ([#20416](https://github.com/facebook/react/pull/20416)) //// - **[56a632adb](https://github.com/facebook/react/commit/56a632adb )**: Double Invoke Effects in __DEV__ (in old reconciler fork) ([#20415](https://github.com/facebook/react/pull/20415)) //// - **[1a2422337](https://github.com/facebook/react/commit/1a2422337 )**: fixed typo ([#20351](https://github.com/facebook/react/pull/20351)) //// - **[a233c9e2a](https://github.com/facebook/react/commit/a233c9e2a )**: Rename internal cache helpers ([#20410](https://github.com/facebook/react/pull/20410)) //// - **[6a4b12b81](https://github.com/facebook/react/commit/6a4b12b81 )**: [Flight] Add rudimentary FS binding ([#20409](https://github.com/facebook/react/pull/20409)) //// - **[7659949d6](https://github.com/facebook/react/commit/7659949d6 )**: Clear `deletions` in `detachFiber` ([#20401](https://github.com/facebook/react/pull/20401)) //// - **[b9680aef7](https://github.com/facebook/react/commit/b9680aef7 )**: Cache react-fetch results in the Node version ([#20407](https://github.com/facebook/react/pull/20407)) //// - **[cdae31ab8](https://github.com/facebook/react/commit/cdae31ab8 )**: Fix typo ([#20279](https://github.com/facebook/react/pull/20279)) //// - **[51a7cfe21](https://github.com/facebook/react/commit/51a7cfe21 )**: Fix typo ([#20300](https://github.com/facebook/react/pull/20300)) //// - **[373b297c5](https://github.com/facebook/react/commit/373b297c5 )**: fix: Fix typo in react-reconciler docs ([#20284](https://github.com/facebook/react/pull/20284)) //// - **[1b5ca9906](https://github.com/facebook/react/commit/1b5ca9906 )**: Fix module ID deduplication ([#20406](https://github.com/facebook/react/pull/20406)) //// - **[5fd9db732](https://github.com/facebook/react/commit/5fd9db732 )**: [Flight] Rename react-transport-... packages to react-server-... ([#20403](https://github.com/facebook/react/pull/20403)) //// - **[ce40f1dc2](https://github.com/facebook/react/commit/ce40f1dc2 )**: Use assets API + writeToDisk instead of directly writing to disk ([#20402](https://github.com/facebook/react/pull/20402)) //// - **[b66ae09b6](https://github.com/facebook/react/commit/b66ae09b6 )**: Track subtreeFlags et al with bubbleProperties //// - **[de75315d7](https://github.com/facebook/react/commit/de75315d7 )**: Track deletions using an array on the parent //// - **[1377e465d](https://github.com/facebook/react/commit/1377e465d )**: Add Placement bit without removing others ([#20398](https://github.com/facebook/react/pull/20398)) //// - **[18d7574ae](https://github.com/facebook/react/commit/18d7574ae )**: Remove `catch` from Scheduler build ([#20396](https://github.com/facebook/react/pull/20396)) //// - **[30dfb8602](https://github.com/facebook/react/commit/30dfb8602 )**: [Flight] Basic scan of the file system to find Client modules ([#20383](https://github.com/facebook/react/pull/20383)) //// - **[9b8060041](https://github.com/facebook/react/commit/9b8060041 )**: Error when the number of parameters to a query changes ([#20379](https://github.com/facebook/react/pull/20379)) //// - **[60e4a76fa](https://github.com/facebook/react/commit/60e4a76fa )**: [Flight] Add rudimentary PG binding ([#20372](https://github.com/facebook/react/pull/20372)) //// - **[88ef95712](https://github.com/facebook/react/commit/88ef95712 )**: Fork ReactFiberLane ([#20371](https://github.com/facebook/react/pull/20371)) //// - **[41c5d00fc](https://github.com/facebook/react/commit/41c5d00fc )**: [Flight] Minimal webpack plugin ([#20228](https://github.com/facebook/react/pull/20228)) //// - **[e23673b51](https://github.com/facebook/react/commit/e23673b51 )**: [Flight] Add getCacheForType() to the dispatcher ([#20315](https://github.com/facebook/react/pull/20315)) //// - **[555eeae33](https://github.com/facebook/react/commit/555eeae33 )**: Add disableNativeComponentFrames flag ([#20364](https://github.com/facebook/react/pull/20364)) //// - **[148ffe3cf](https://github.com/facebook/react/commit/148ffe3cf )**: Failing test for Client reconciliation ([#20318](https://github.com/facebook/react/pull/20318)) //// - **[a2a025537](https://github.com/facebook/react/commit/a2a025537 )**: Fixed invalid DevTools work tags ([#20362](https://github.com/facebook/react/pull/20362)) //// - **[5711811da](https://github.com/facebook/react/commit/5711811da )**: Reconcile element types of lazy component yielding the same type ([#20357](https://github.com/facebook/react/pull/20357)) //// - **[3f73dcee3](https://github.com/facebook/react/commit/3f73dcee3 )**: Support named exports from client references ([#20312](https://github.com/facebook/react/pull/20312)) //// - **[565148d75](https://github.com/facebook/react/commit/565148d75 )**: Disallow *.server.js imports from any other files ([#20309](https://github.com/facebook/react/pull/20309)) //// - **[e6a0f2763](https://github.com/facebook/react/commit/e6a0f2763 )**: Profiler: Improve nested-update checks ([#20299](https://github.com/facebook/react/pull/20299)) //// - **[d93b58a5e](https://github.com/facebook/react/commit/d93b58a5e )**: Add flight specific entry point for react package ([#20304](https://github.com/facebook/react/pull/20304)) //// - **[a81c02ac1](https://github.com/facebook/react/commit/a81c02ac1 )**: Profiler onNestedUpdateScheduled accepts id as first param ([#20293](https://github.com/facebook/react/pull/20293)) //// - **[ac2cff4b1](https://github.com/facebook/react/commit/ac2cff4b1 )**: Warn if commit phase error thrown in detached tree ([#20286](https://github.com/facebook/react/pull/20286)) //// - **[0f83a64ed](https://github.com/facebook/react/commit/0f83a64ed )**: Regression test: Missing unmount after re-order ([#20285](https://github.com/facebook/react/pull/20285)) //// - **[ebf158965](https://github.com/facebook/react/commit/ebf158965 )**: Add best-effort documentation for third-party renderers ([#20278](https://github.com/facebook/react/pull/20278)) //// - **[82e99e1b0](https://github.com/facebook/react/commit/82e99e1b0 )**: Add Node ESM Loader and Register Entrypoints ([#20274](https://github.com/facebook/react/pull/20274)) //// - **[bf7b7aeb1](https://github.com/facebook/react/commit/bf7b7aeb1 )**: findDOMNode: Remove return pointer mutation ([#20272](https://github.com/facebook/react/pull/20272)) //// - **[369c3db62](https://github.com/facebook/react/commit/369c3db62 )**: Add separate ChildDeletion flag ([#20264](https://github.com/facebook/react/pull/20264)) //// - **[765e89b90](https://github.com/facebook/react/commit/765e89b90 )**: Reset new fork to old fork ([#20254](https://github.com/facebook/react/pull/20254)) //// - **[7548dd573](https://github.com/facebook/react/commit/7548dd573 )**: Properly reset Profiler nested-update flag ([#20253](https://github.com/facebook/react/pull/20253)) //// - **[b44e4b13a](https://github.com/facebook/react/commit/b44e4b13a )**: Check for deletions in `hadNoMutationsEffects` ([#20252](https://github.com/facebook/react/pull/20252)) //// - **[3ebf05183](https://github.com/facebook/react/commit/3ebf05183 )**: Add new effect fields to old fork, and vice versa ([#20246](https://github.com/facebook/react/pull/20246)) //// - **[2fbcc9806](https://github.com/facebook/react/commit/2fbcc9806 )**: Remove cycle between ReactFiberHooks and ReactInternalTypes ([#20242](https://github.com/facebook/react/pull/20242)) //// - **[504222dcd](https://github.com/facebook/react/commit/504222dcd )**: Add Node ESM build option ([#20243](https://github.com/facebook/react/pull/20243)) //// - **[1b96ee444](https://github.com/facebook/react/commit/1b96ee444 )**: Remove noinline directives from new commit phase ([#20241](https://github.com/facebook/react/pull/20241)) //// - **[760d9ab57](https://github.com/facebook/react/commit/760d9ab57 )**: Scheduling profiler tweaks ([#20215](https://github.com/facebook/react/pull/20215)) //// - **[9403c3b53](https://github.com/facebook/react/commit/9403c3b53 )**: Add Profiler callback when nested updates are scheduled ([#20211](https://github.com/facebook/react/pull/20211)) //// - **[62efd9618](https://github.com/facebook/react/commit/62efd9618 )**: use-subscription@1.5.1 //// - **[e7006d67d](https://github.com/facebook/react/commit/e7006d67d )**: Widen peer dependency range of use-subscription ([#20225](https://github.com/facebook/react/pull/20225)) //// - **[15df051c9](https://github.com/facebook/react/commit/15df051c9 )**: Add warning if return pointer is inconsistent ([#20219](https://github.com/facebook/react/pull/20219)) //// - **[9aca239f1](https://github.com/facebook/react/commit/9aca239f1 )**: Improved dev experience when DevTools hook is disabled ([#20208](https://github.com/facebook/react/pull/20208)) //// - **[12627f93b](https://github.com/facebook/react/commit/12627f93b )**: Perform hasOwnProperty check in Relay Flight ([#20220](https://github.com/facebook/react/pull/20220)) //// - **[163199d8c](https://github.com/facebook/react/commit/163199d8c )**: Dedupe module id generation ([#20172](https://github.com/facebook/react/pull/20172)) //// - **[76a6dbcb9](https://github.com/facebook/react/commit/76a6dbcb9 )**: [Flight] Encode Symbols as special rows that can be referenced by models … ([#20171](https://github.com/facebook/react/pull/20171)) //// - **[35e53b465](https://github.com/facebook/react/commit/35e53b465 )**: [Flight] Simplify Relay row protocol ([#20168](https://github.com/facebook/react/pull/20168)) //// - **[16e6dadba](https://github.com/facebook/react/commit/16e6dadba )**: Encode throwing server components as lazy throwing references ([#20217](https://github.com/facebook/react/pull/20217)) //// - **[c896cf961](https://github.com/facebook/react/commit/c896cf961 )**: Set return pointer when reusing current tree ([#20212](https://github.com/facebook/react/pull/20212)) //// - **[089866015](https://github.com/facebook/react/commit/089866015 )**: Add version of scheduler that only swaps MessageChannel for postTask ([#20206](https://github.com/facebook/react/pull/20206)) //// - **[393c452e3](https://github.com/facebook/react/commit/393c452e3 )**: Add "nested-update" phase to Profiler API ([#20163](https://github.com/facebook/react/pull/20163)) //// - **[13a62feab](https://github.com/facebook/react/commit/13a62feab )**: Fix path for SchedulerFeatureFlags ([#20200](https://github.com/facebook/react/pull/20200)) //// - **[7a73d6a0f](https://github.com/facebook/react/commit/7a73d6a0f )**: (Temporarily) revert unmounting error boundaries changes ([#20147](https://github.com/facebook/react/pull/20147)) //// - **[c29710a57](https://github.com/facebook/react/commit/c29710a57 )**: fix: useImperativeMethods to useImperativeHandle ([#20194](https://github.com/facebook/react/pull/20194)) //// jest_e2e[run_all_tests] Changelog: [General][Changed] - React Native sync for revisions c3e20f1...4d28eca Reviewed By: mdvacca Differential Revision: D26583597 fbshipit-source-id: a042df12c587fa9248d8de6f0b21b3ab231b3a7d --- Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 14241 ++++++++------- .../implementations/ReactFabric-prod.fb.js | 3403 ++-- .../ReactFabric-profiling.fb.js | 3556 ++-- .../ReactNativeRenderer-dev.fb.js | 14521 ++++++++-------- .../ReactNativeRenderer-prod.fb.js | 3427 ++-- .../ReactNativeRenderer-profiling.fb.js | 3580 ++-- Libraries/Renderer/shims/ReactFabric.js | 2 + Libraries/Renderer/shims/ReactNativeTypes.js | 13 +- .../shims/ReactNativeViewConfigRegistry.js | 4 + .../shims/createReactNativeComponentClass.js | 2 + 11 files changed, 22485 insertions(+), 20266 deletions(-) diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index 974273dc6854dd..bae76f0ce3d759 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -c3e20f18fe37993ddcbf11dccb55663b4c0d02fd \ No newline at end of file +0cf9fc10ba9d47099f3507080dd736054d877a20 \ 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 4d07117f346fb9..5d488ee7b2f9d1 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2493,14 +2493,27 @@ function getFiberCurrentPropsFromNode$1(inst) { // Module provided by RN: var ReactFabricGlobalResponderHandler = { onChange: function(from, to, blockNativeResponder) { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder - ); + var fromOrTo = from || to; + var isFabric = !!fromOrTo.stateNode.canonical._internalInstanceHandle; + + if (isFabric) { + if (from) { + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, false); + } + + if (to) { + nativeFabricUIManager.setIsJSResponder(to.stateNode.node, true); + } } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); + } else { + ReactNativePrivateInterface.UIManager.clearJSResponder(); + } } } }; @@ -2547,12 +2560,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2568,12 +2581,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2647,6 +2660,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -2684,8 +2700,10 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -2703,53 +2721,84 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 16384; + 32768; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 65536; // Static tags describe aspects of a fiber that are not specific to a render, +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var PassiveStatic = + /* */ + 131072; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = PassiveStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -2989,38 +3038,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3689,2031 +3728,2079 @@ function dispatchEvent(target, topLevelType, nativeEvent) { // where it would do it. } -// can re-export everything from this module. +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); } -} // Mutation (when unsupported) +} -var supportsMutation = false; -var commitMount = shim; -var clearContainer = shim; +// Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -// can re-export everything from this module. +var NoPriority = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. -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$1; -var isSuspenseInstanceFallback = shim$1; -var hydrateTextInstance = shim$1; +var now = + initialTimeMs < 10000 + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority; -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, - cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage.createChildSet, - appendChildNode = _nativeFabricUIManage.appendChild, - appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, - completeRoot = _nativeFabricUIManage.completeRoot, - registerEventHandler = _nativeFabricUIManage.registerEventHandler, - fabricMeasure = _nativeFabricUIManage.measure, - fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage.measureLayout, - sendAccessibilityEvent = _nativeFabricUIManage.sendAccessibilityEvent; -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. + case Scheduler_UserBlockingPriority: + return UserBlockingPriority; -var nextReactTag = 2; + case Scheduler_NormalPriority: + return NormalPriority; -// TODO: Remove this conditional once all changes have propagated. -if (registerEventHandler) { - /** - * Register the event emitter with the native bridge - */ - registerEventHandler(dispatchEvent); -} -/** - * This is used for refs on host components. - */ + case Scheduler_LowPriority: + return LowPriority; -var ReactFabricHostComponent = /*#__PURE__*/ (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; - } + case Scheduler_IdlePriority: + return IdlePriority; - var _proto = ReactFabricHostComponent.prototype; + default: { + throw Error("Unknown priority level."); + } + } +} - _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority: + return Scheduler_ImmediatePriority; - _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; + case UserBlockingPriority: + return Scheduler_UserBlockingPriority; - _proto.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + case NormalPriority: + return Scheduler_NormalPriority; - _proto.measureInWindow = function measureInWindow(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + case LowPriority: + return Scheduler_LowPriority; - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) /* currently unused */ - { - if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) - ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } + case IdlePriority: + return Scheduler_IdlePriority; - return; + default: { + throw Error("Unknown priority level."); } + } +} - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we + // forget to explicitly flush. - _proto.setNativeProps = function setNativeProps(nativeProps) { { - error("Warning: setNativeProps is not currently supported in Fabric"); + // Flush the queue in the next tick. + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); } - - return; - }; - - return ReactFabricHostComponent; -})(); // eslint-disable-next-line no-unused-expressions -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); -} -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; - var viewConfig = getViewConfigForType(type); - - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } - } - } - - var updatePayload = create(props, viewConfig.validAttributes); - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); - return { - node: node, - canonical: component - }; -} -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); - } - - var tag = nextReactTag; - nextReactTag += 2; - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - }, // props - internalInstanceHandle // instance handle - ); - return { - node: node - }; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; - - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; } else { - return parentHostContext; + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); } } -function getPublicInstance(instance) { - return instance.canonical; -} -function prepareForCommit(containerInfo) { - // Noop - return null; +function cancelCallback(callbackNode) { + Scheduler_cancelCallback(callbackNode); } -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - var viewConfig = instance.canonical.viewConfig; - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props - // in the commit phase but there is no host config hook to do it yet. - // So instead we hack it by updating it in the render phase. +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } - instance.canonical.currentProps = newProps; - return updatePayload; -} -function resetAfterCommit(containerInfo) { - // Noop + flushSyncCallbackQueueImpl(); } -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // The Fabric renderer is secondary to the existing React Native renderer. -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; // ------------------- -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone; - if (keepChildren) { - if (updatePayload !== null) { - clone = cloneNodeWithNewProps(node, updatePayload); - } else { - clone = cloneNode(node); - } - } else { - if (updatePayload !== null) { - clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); - } else { - clone = cloneNodeWithNewChildren(node); - } - } +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; - return { - node: clone, - canonical: instance.canonical - }; -} -function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { - var viewConfig = instance.canonical.viewConfig; - var node = instance.node; - var updatePayload = create( { - style: { - display: "none" + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; + + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick + + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ); + throw error; + } finally { + isFlushingSyncQueue = false; } - }, - viewConfig.validAttributes - ); - return { - node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical - }; -} -function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { - throw new Error("Not yet implemented."); -} -function createContainerChildSet(container) { - return createChildNodeSet(container); -} -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop + } + } } -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; - -function disabledLog() {} +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. +// If those values are changed that package should be rebuilt and redeployed. -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLane = + /* */ + 8; +var InputContinuousHydrationLane = + /* */ + 16; +var InputContinuousLane = + /* */ + 32; +var DefaultHydrationLane = + /* */ + 64; +var DefaultLane = + /* */ + 128; +var TransitionHydrationLane = + /* */ + 256; +var TransitionLanes = + /* */ + 8388096; +var TransitionLane1 = + /* */ + 512; +var TransitionLane2 = + /* */ + 1024; +var TransitionLane3 = + /* */ + 2048; +var TransitionLane4 = + /* */ + 4096; +var TransitionLane5 = + /* */ + 8192; +var TransitionLane6 = + /* */ + 16384; +var TransitionLane7 = + /* */ + 32768; +var TransitionLane8 = + /* */ + 65536; +var TransitionLane9 = + /* */ + 131072; +var TransitionLane10 = + /* */ + 262144; +var TransitionLane11 = + /* */ + 524288; +var TransitionLane12 = + /* */ + 1048576; +var TransitionLane13 = + /* */ + 2097152; +var TransitionLane14 = + /* */ + 4194304; +var RetryLanes = + /* */ + 125829120; +var RetryLane1 = + /* */ + 8388608; +var RetryLane2 = + /* */ + 16777216; +var RetryLane3 = + /* */ + 33554432; +var RetryLane4 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; +// Used by getHighestPriorityLanes and getNextLanes: - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. +var return_highestLanePriority = DefaultLanePriority; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ - } +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return_highestLanePriority = SyncLanePriority; + return SyncLane; - disabledDepth++; - } -} -function reenableLogs() { - { - disabledDepth--; + case SyncBatchedLane: + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case InputDiscreteHydrationLane: + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; + + case InputDiscreteLane: + return_highestLanePriority = InputDiscreteLanePriority; + return InputDiscreteLane; + + case InputContinuousHydrationLane: + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; + + case InputContinuousLane: + return_highestLanePriority = InputContinuousLanePriority; + return InputContinuousLane; + + case DefaultHydrationLane: + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + + case DefaultLane: + return_highestLanePriority = DefaultLanePriority; + return DefaultLane; + + case TransitionHydrationLane: + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + return_highestLanePriority = TransitionPriority; + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return_highestLanePriority = RetryLanePriority; + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + + case IdleHydrationLane: + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + + case IdleLane: + return_highestLanePriority = IdleLanePriority; + return IdleLane; + + case OffscreenLane: + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); - } + return_highestLanePriority = DefaultLanePriority; + return lanes; } } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + case UserBlockingPriority: + return InputContinuousLanePriority; - return describeComponentFrame(name, source, ownerName); - } -} -var componentFrameCache; + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); + case IdlePriority: + return IdleLanePriority; + + default: + return NoLanePriority; + } } -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; - if (match) { - var pathBeforeSlash = match[1]; + case NoLanePriority: + return NoPriority; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } + default: { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; } - - return "\n in " + (name || "Unknown") + sourceInfo; } +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; - } - - var name = fn.displayName || fn.name || null; - var ownerName = null; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. - return describeComponentFrame(name, source, ownerName); - } -} - -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } - - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); - } - } - - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); - } - - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); - - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); - } + if (expiredLanes !== NoLanes) { + // TODO: Should entangle with SyncLane + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; + } + } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } } } } - return ""; -} + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); + if ( + nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLanePriority === DefaultLanePriority && + wipLanePriority === TransitionPriority) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); + return_highestLanePriority = nextLanePriority; } - } -} - -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); - - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } - - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } - - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); - - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); - - setCurrentlyValidatingElement(null); - } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + var entangledLanes = root.entangledLanes; - error("Failed %s type: %s", location, error$1.message); + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - setCurrentlyValidatingElement(null); - } - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; } } -} -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; -} - -var index = -1; - -function createCursor(defaultValue) { - return { - current: defaultValue - }; + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } - - return; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } - - cursor.current = valueStack[index]; - valueStack[index] = null; - { - fiberStack[index] = null; + lanes &= ~lane; } - index--; + return mostRecentEventTime; } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; - - { - fiberStack[index] = fiber; - } - - cursor.current = value; -} - -var warnedAboutMissingGetChildContext; +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; -{ - warnedAboutMissingGetChildContext = {}; + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; + } } -var emptyContextObject = {}; - -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. - -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + var lanes = pendingLanes; -var previousContext = emptyContextObject; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - return contextStackCursor.current; + lanes &= ~lane; } -} +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } + + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } + + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; } +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case NoLanePriority: + break; - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. + case SyncLanePriority: + return SyncLane; - var instance = workInProgress.stateNode; + case SyncBatchedLanePriority: + return SyncBatchedLane; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + case InputDiscreteLanePriority: + return InputDiscreteLane; - var context = {}; + case InputContinuousLanePriority: + return InputContinuousLane; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + case DefaultLanePriority: + return DefaultLane; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + case TransitionPriority: // Should be handled by findTransitionLane instead - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); - } + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; - return context; + case IdleLanePriority: + return IdleLane; } -} -function hasContextChanged() { { - return didPerformWorkStackCursor.current; + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } } +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; } + + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; } + + return lane; } -function popTopLevelContextObject(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); - } +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); } -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); +} - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } - return parentContext; - } - - var childContext = instance.getChildContext(); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - } - } + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. - return Object.assign({}, parentContext, childContext); - } + eventTimes[index] = eventTime; } +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. - - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; +} +function markRootExpired(root, expiredLanes) { + root.expiredLanes |= expiredLanes & root.pendingLanes; +} +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLane) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; - - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - } + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + var lanes = noLongerPendingLanes; - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; - - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } - - break; - } - } - - node = node.return; - } while (node !== null); + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; } + + lanes &= ~lane; } } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; +var log = Math.log; +var LN2 = Math.LN2; -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + return (31 - ((log(lanes) / LN2) | 0)) | 0; +} - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now$1 = Scheduler.unstable_now; + +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); } +} +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. +// can re-export everything from this module. - return true; +function shim() { + { + throw Error( + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." + ); } +} // Mutation (when unsupported) - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. +var supportsMutation = false; +var commitMount = shim; +var clearContainer = shim; - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists +// can re-export everything from this module. - return true; -} -function onScheduleRoot(root, children) { +function shim$1() { { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - - error("React instrumentation encountered an error: %s", err); - } - } - } + throw Error( + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + ); } -} -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - error("React instrumentation encountered an error: %s", err); - } - } - } - } -} -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +var nextReactTag = 2; - error("React instrumentation encountered an error: %s", err); - } - } - } - } +// TODO: Remove this conditional once all changes have propagated. +if (registerEventHandler) { + /** + * Register the event emitter with the native bridge + */ + registerEventHandler(dispatchEvent); } +/** + * This is used for refs on host components. + */ -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) +var ReactFabricHostComponent = /*#__PURE__*/ (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } -} -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: - -var return_highestLanePriority = DefaultLanePriority; - -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; - } - - if ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } - - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - } - - var inputDiscreteLanes = InputDiscreteLanes & lanes; - - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; } - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } + var _proto = ReactFabricHostComponent.prototype; - var inputContinuousLanes = InputContinuousLanes & lanes; + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; - } + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; - if ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - } + _proto.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - var defaultLanes = DefaultLanes & lanes; + _proto.measureInWindow = function measureInWindow(callback) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; - } + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; - } + return; + } - var transitionLanes = TransitionLanes & lanes; + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; - } + _proto.setNativeProps = function setNativeProps(nativeProps) { + { + error("Warning: setNativeProps is not currently supported in Fabric"); + } - var retryLanes = RetryLanes & lanes; + return; + }; - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } + return ReactFabricHostComponent; +})(); // eslint-disable-next-line no-unused-expressions +function appendInitialChild(parentInstance, child) { + appendChildNode(parentInstance.node, child.node); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = nextReactTag; + nextReactTag += 2; + var viewConfig = getViewConfigForType(type); - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); + } + } } - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; - } - - var idleLanes = IdleLanes & lanes; - - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; - } - - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; + var updatePayload = create(props, viewConfig.validAttributes); + var node = createNode( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload, // props + internalInstanceHandle // internalInstanceHandle + ); + var component = new ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ); + return { + node: node, + canonical: component + }; +} +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); } - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - - return_highestLanePriority = DefaultLanePriority; - return lanes; + var tag = nextReactTag; + nextReactTag += 2; + var node = createNode( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + }, // props + internalInstanceHandle // instance handle + ); + return { + node: node + }; } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; + } +} +function getPublicInstance(instance) { + return instance.canonical; +} +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + var viewConfig = instance.canonical.viewConfig; + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props + // in the commit phase but there is no host config hook to do it yet. + // So instead we hack it by updating it in the render phase. - case IdlePriority: - return IdleLanePriority; + instance.canonical.currentProps = newProps; + return updatePayload; +} +function resetAfterCommit(containerInfo) { + // Noop +} +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; // ------------------- +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone; - default: - return NoLanePriority; + if (keepChildren) { + if (updatePayload !== null) { + clone = cloneNodeWithNewProps(node, updatePayload); + } else { + clone = cloneNode(node); + } + } else { + if (updatePayload !== null) { + clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); + } else { + clone = cloneNodeWithNewChildren(node); + } } + + return { + node: clone, + canonical: instance.canonical + }; +} +function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { + var viewConfig = instance.canonical.viewConfig; + var node = instance.node; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + return { + node: cloneNodeWithNewProps(node, updatePayload), + canonical: instance.canonical + }; +} +function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { + throw new Error("Not yet implemented."); +} +function createContainerChildSet(container) { + return createChildNodeSet(container); +} +function appendChildToContainerChildSet(childSet, child) { + appendChildNodeToSet(childSet, child.node); +} +function finalizeContainerChildren(container, newChildren) { + completeRoot(container, newChildren); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; +function disabledLog() {} - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; +disabledLog.__reactDisabledLog = true; +function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - case NoLanePriority: - return NoPriority; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } + + disabledDepth++; } } -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; +function reenableLogs() { + { + disabledDepth--; - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); + } } +} - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + return describeComponentFrame(name, source, ownerName); + } +} +var componentFrameCache; - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". + + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + + if (match) { + var pathBeforeSlash = match[1]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; } } } + + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. + return "\n in " + (name || "Unknown") + sourceInfo; +} - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); + } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; + var name = fn.displayName || fn.name || null; + var ownerName = null; - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. - var entangledLanes = root.entangledLanes; + return describeComponentFrame(name, source, ownerName); + } +} - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); } } - return nextLanes; -} -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; - } + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); + } - lanes &= ~lane; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); + + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } } - return mostRecentEventTime; + return ""; } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; - } -} - -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. - - var lanes = pendingLanes; - - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; - - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); } - - lanes &= ~lane; - } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; } - - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; - } - - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; } -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; -} -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; - - case SyncLanePriority: - return SyncLane; - case SyncBatchedLanePriority: - return SyncBatchedLane; +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - return _lane; - } + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); - } + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - return _lane2; - } + setCurrentlyValidatingElement(null); + } - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + error("Failed %s type: %s", location, error$1.message); - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); + setCurrentlyValidatingElement(null); } } - - return _lane3; } + } +} - case TransitionPriority: // Should be handled by findTransitionLane instead +var valueStack = []; +var fiberStack; - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; +{ + fiberStack = []; +} - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); +var index = -1; - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} + +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); + } - return lane; + return; } { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. - -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + cursor.current = valueStack[index]; + valueStack[index] = null; - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); - } + { + fiberStack[index] = null; } - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. + index--; +} -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); + { + fiberStack[index] = fiber; } - return lane; + cursor.current = value; } -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} +var warnedAboutMissingGetChildContext; -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; +{ + warnedAboutMissingGetChildContext = {}; } -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} +var emptyContextObject = {}; -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); -} +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). +var previousContext = emptyContextObject; -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + } - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + return contextStackCursor.current; } - - return laneMap; } -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - eventTimes[index] = eventTime; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } } -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work + var instance = workInProgress.stateNode; - var lanes = noLongerPendingLanes; + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; + } - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + var context = {}; + + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } + + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. + + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; } } -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var log = Math.log; -var LN2 = Math.LN2; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } +} -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } +} - return (31 - ((log(lanes) / LN2) | 0)) | 0; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } - case Scheduler_NormalPriority: - return NormalPriority$1; + return parentContext; + } - case Scheduler_LowPriority: - return LowPriority$1; + var childContext = instance.getChildContext(); - case Scheduler_IdlePriority: - return IdlePriority$1; + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } - default: { - throw Error("Unknown priority level."); + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); } + + return Object.assign({}, parentContext, childContext); } } -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - case NormalPriority$1: - return Scheduler_NormalPriority; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; + } +} - case LowPriority$1: - return Scheduler_LowPriority; +function invalidateContextProvider(workInProgress, type, didChange) { + { + var instance = workInProgress.stateNode; - case IdlePriority$1: - return Scheduler_IdlePriority; + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } - default: { - throw Error("Unknown priority level."); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. + + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } } -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); - } + var node = fiber; - return fakeCallbackNode; -} -function cancelCallback(callbackNode) { - if (callbackNode !== fakeCallbackNode) { - Scheduler_cancelCallback(callbackNode); + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; + + case ClassComponent: { + var Component = node.type; + + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } + + break; + } + } + + node = node.return; + } while (node !== null); + + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } } } -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); + +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } - flushSyncCallbackQueueImpl(); -} + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; + } + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. + + return true; + } + + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists + + return true; +} +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError ); - throw error; - } finally { - isFlushingSyncQueue = false; + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } } } +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; + // TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; +// +// TODO: 17.0.2 has not been released to NPM; +// It exists as a placeholder so that DevTools can support work tag changes between releases. +// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js +var ReactVersion = "17.0.2"; -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead +var NoMode = + /* */ + 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; +var BlockingMode = + /* */ + 1; +var ConcurrentMode = + /* */ + 2; +var ProfileMode = + /* */ + 4; +var DebugTracingMode = + /* */ + 8; +var StrictLegacyMode = + /* */ + 16; var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; var NoTransition = 0; @@ -5891,7 +5978,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -5922,7 +6009,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -5935,7 +6022,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -5949,7 +6036,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -5963,7 +6050,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6281,9 +6368,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue2, providerFiber); context._currentValue2 = nextValue; @@ -6304,10 +6389,9 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue2 = currentValue; @@ -6394,20 +6478,35 @@ function propagateContextChange( // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check - enqueueUpdate(fiber, update); - } + var updateQueue = fiber.updateQueue; - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + sharedQueue.pending = update; + } + } + + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; if (alternate !== null) { alternate.lanes = mergeLanes(alternate.lanes, renderLanes); @@ -6538,6 +6637,48 @@ function readContext(context, observedBits) { return context._currentValue2; } +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +function enqueueInterleavedUpdates() { + // Transfer the interleaved updates onto the main queue. Each queue has a + // `pending` field and an `interleaved` field. When they are not null, they + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } +} + var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6560,7 +6701,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6593,7 +6736,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6602,17 +6745,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6630,6 +6791,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -6731,7 +6919,7 @@ function getStateFromUpdate( var nextState = payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -6769,7 +6957,7 @@ function getStateFromUpdate( partialState = _payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -6959,7 +7147,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7100,7 +7305,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7149,7 +7354,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7168,7 +7377,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7186,7 +7399,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7203,7 +7420,7 @@ function checkShouldComponentUpdate( if (typeof instance.shouldComponentUpdate === "function") { { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7539,7 +7756,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7752,7 +7969,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -7796,7 +8013,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } @@ -7858,7 +8077,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } return false; @@ -7904,13 +8125,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8160,7 +8385,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8262,12 +8487,14 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { + var childString = Object.prototype.toString.call(newChild); + { throw Error( "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : childString) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8290,7 +8517,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // This wrapper function exists because I expect to clone the code in each path +} // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8300,23 +8527,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8380,7 +8600,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8388,7 +8608,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8397,7 +8617,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8418,10 +8638,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements ) { // Move based on index var existing = useFiber(current, element.props); @@ -8560,16 +8796,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8627,16 +8853,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9130,45 +9346,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9599,21 +9813,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -9709,6 +9908,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -9994,7 +10199,20 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -10008,8 +10226,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10160,6 +10383,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10297,6 +10522,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10424,11 +10671,48 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentName(currentlyRenderingFiber$1.type); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10564,6 +10848,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10611,6 +10897,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -10704,7 +10992,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -10720,15 +11008,19 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { } function mountEffect(create, deps) { - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + { + return mountEffectImpl(Update, Layout, create, deps); + } } function updateLayoutEffect(create, deps) { @@ -10780,12 +11072,15 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + + { + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } } function updateImperativeHandle(ref, create, deps) { @@ -10940,15 +11235,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 + priorityLevel < UserBlockingPriority + ? UserBlockingPriority : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11060,19 +11355,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -11083,7 +11366,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11128,7 +11451,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -11150,6 +11490,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11279,6 +11620,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11376,6 +11718,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11473,6 +11816,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11570,6 +11914,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11682,6 +12027,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11794,6 +12140,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -11836,218 +12183,621 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; var prevDispatcher = ReactCurrentDispatcher$1.current; ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; +} + +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; + +function getCommitTime() { + return commitTime; +} + +function recordCommitTime() { + commitTime = now$1(); +} + +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} + +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 +) { + // 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; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); + } + } + } + + 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 (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); + } + + 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 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; + + { + 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. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + 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", + getComponentName(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 _type = Component.type; + 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", + getComponentName(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one 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 + + 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, + 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; + + 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 { + 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", + getComponentName(outerMemoType) + ); + } } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + } + } - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + if (current !== null) { + var prevProps = current.memoizedProps; - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; + 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 (!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 accumlated 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; } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; + } + } + + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; +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. -function getCommitTime() { - return commitTime; -} + var spawnedCachePool = null; -function recordCommitTime() { - commitTime = now$1(); -} + 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. + // TODO: Figure out what we should do in Blocking mode. + 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; -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); + 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. - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); - } -} + { + markSpawnedWork(OffscreenLane); + } -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} + 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. -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; + 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. - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); } + } else { + // Rendering a visible tree. + var _subtreeRenderLanes; - profilerStartTime = -1; - } -} + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; + 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; + } - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; + pushRenderLanes(workInProgress, _subtreeRenderLanes); } -} -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; + 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. -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; -} +var updateLegacyHiddenComponent = updateOffscreenComponent; -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 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 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 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. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function updateForwardRef( +function updateFunctionComponent( 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 @@ -12065,8 +12815,12 @@ function updateForwardRef( } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -12077,22 +12831,22 @@ function updateForwardRef( nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); } finally { @@ -12113,3049 +12867,3319 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( +function updateClassComponent( 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; - - { - 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. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } - - { - var innerPropTypes = type.propTypes; + { + 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) { - // 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", - getComponentName(type) + getComponentName(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. - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; - } - - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + var hasContext; - 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", - getComponentName(_type) - ); - } + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - var currentChild = current.child; // This is always exactly one 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 - - 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. + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - workInProgress.flags |= PerformedWork; - var newChild = createWorkInProgress(currentChild, nextProps); - newChild.ref = workInProgress.ref; - newChild.return = workInProgress; - workInProgress.child = newChild; - return newChild; -} + 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 -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; + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. - 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; + 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 + ); + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + { + var inst = workInProgress.stateNode; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); - } + 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.", + getComponentName(workInProgress.type) || "a component" + ); } + + didWarnAboutReassigningProps = true; } } - if (current !== null) { - var prevProps = current.memoizedProps; + return nextUnitOfWork; +} - 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 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 (!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 accumlated 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 (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); } + + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); -} + var instance = workInProgress.stateNode; // Rerender -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" ) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. - var nextState = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - var nextBaseLanes; + // 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 (prevState !== null) { - var prevBaseLanes = prevState.baseLanes; - nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); - } else { - nextBaseLanes = renderLanes; - } // Schedule this fiber to re-render at offscreen priority. Then bailout. + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); - { - markSpawnedWork(OffscreenLane); + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + instance.render(); + } finally { + reenableLogs(); + } } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes - }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. + setIsRendering(false); + } + } // React DevTools reads this flag. - pushRenderLanes(workInProgress, nextBaseLanes); - return null; - } else { - // Rendering at offscreen, so we can clear the base lanes. - var _nextState2 = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. + workInProgress.flags |= PerformedWork; - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } + 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 { - var _subtreeRenderLanes; - - if (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state + 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 = 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; - } + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. - pushRenderLanes(workInProgress, _subtreeRenderLanes); + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - 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. +} -var updateLegacyHiddenComponent = updateOffscreenComponent; +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + pushHostContainer(workInProgress, root.containerInfo); } -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, +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + 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 (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; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current, workInProgress) { + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateLanes, 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 (_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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } + workInProgress.flags |= Placement; } - var context; + 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. - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - if (workInProgress.mode & StrictMode) { - disableLogs(); + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - } finally { - reenableLogs(); } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - setIsRendering(false); + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } + } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + var hint = ""; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + { + 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 + ); + } } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _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 (_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 + + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. + + 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 hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } + + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} + +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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(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. + workInProgress.flags |= Placement; + } - var hasContext; + var props = workInProgress.pendingProps; + var context; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + var value; - 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 + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + 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 + ); - 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, + didWarnAboutBadClass[componentName] = true; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, workInProgress, Component, - nextProps, + props, + context, renderLanes ); - } + setIsRendering(false); + } // React DevTools reads this flag. - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + workInProgress.flags |= PerformedWork; { - var inst = workInProgress.stateNode; + // 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 = getComponentName(Component) || "Unknown"; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { + if (!didWarnAboutModulePatternComponent[_componentName]) { error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" + "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 ); - } - didWarnAboutReassigningProps = true; + didWarnAboutModulePatternComponent[_componentName] = true; + } } } - return nextUnitOfWork; -} + 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 = getComponentName(Component) || "Unknown"; -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 (!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 + ); - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - var instance = workInProgress.stateNode; // Rerender + 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. - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + var hasContext = false; - 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 (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - { - stopProfilerTimerIfRunning(); + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); } + + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); } else { - { - setIsRendering(true); - nextChildren = instance.render(); + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - if (workInProgress.mode & StrictMode) { + { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { - instance.render(); + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); } 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. + reconcileChildren(null, workInProgress, value, renderLanes); - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + { + validateFunctionComponentInDev(workInProgress, Component); + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); + return workInProgress.child; } - - return workInProgress.child; } -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, 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" + ); + } + } - pushHostContainer(workInProgress, root.containerInfo); -} + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - 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 warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - var nextChildren = nextState.element; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - var root = workInProgress.stateNode; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - 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; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } } - } 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); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - 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; + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } } - - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - return null; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; } -function mountLazyComponent( - _current, +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, - 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 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; - workInProgress.flags |= Placement; + 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. + + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} + +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} + +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } } - 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. + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + 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. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } + } + + 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) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - child = updateFunctionComponent( - null, + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, + 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, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - case ForwardRef: { + 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. + + workInProgress.lanes = SomeRetryLane; + { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); + markSpawnedWork(SomeRetryLane); } - child = updateForwardRef( - null, + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, renderLanes ); - return child; } + } 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 MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } + 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 + ); + + 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; - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; + 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; + } } } +} - var hint = ""; +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; +} - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; +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 & BlockingMode) === 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; } - } // 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 + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } + + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -function mountIncompleteClassComponent( - _current, +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, - Component, - nextProps, + primaryChildren, 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 + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } - 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. + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - var hasContext; + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } } - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); + workInProgress.child = primaryChildFragment; + return primaryChildFragment; } -function mountIndeterminateComponent( - _current, +function updateSuspenseFallbackChildren( + current, workInProgress, - Component, + primaryChildren, + fallbackChildren, 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); - } + var mode = workInProgress.mode; + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; - prepareToReadContext(workInProgress, renderLanes); - var value; + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === 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 ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + 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. - 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 - ); + 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.) - didWarnAboutBadClass[componentName] = true; - } - } + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + var fallbackChildFragment; - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes + if (currentFallbackChildFragment !== null) { + fallbackChildFragment = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren ); - setIsRendering(false); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - - { - // 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 = getComponentName(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 - ); + } 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. - didWarnAboutModulePatternComponent[_componentName] = true; - } - } + fallbackChildFragment.flags |= Placement; } - 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 = getComponentName(Component) || "Unknown"; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - 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 scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + scheduleWorkOnParentPath(fiber.return, 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. +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; - var hasContext = false; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; + 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; } - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; - - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + if (node === workInProgress) { + return; } - 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 (workInProgress.mode & StrictMode) { - disableLogs(); - - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.return; } - reconcileChildren(null, workInProgress, value, renderLanes); + node.sibling.return = node.return; + node = node.sibling; + } +} - { - validateFunctionComponentInDev(workInProgress, Component); +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 (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } - return workInProgress.child; + row = row.sibling; } + + return lastContentRow; } -function validateFunctionComponentInDev(workInProgress, Component) { +function validateRevealOrder(revealOrder) { { - if (Component) { - if (Component.childContextTypes) { - error( - "%s(...): childContextTypes cannot be defined on a function component.", - Component.displayName || Component.name || "Component" - ); - } - } + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + 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() + ); - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + break; + } - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + 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 (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + break; + } - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + break; + } + } else { error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder ); } } + } +} - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 + '"%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; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } - - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { error( - "%s: Function components do not support contextType.", - _componentName4 + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; } } } } -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; - -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes - }; -} +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) - }; -} // TODO: Probably should inline this back + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; -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; + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - 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. + } - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + return true; } -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; - } - } + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - 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. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); + _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 + ); + } } } } +} - 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. +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode +) { + var renderState = workInProgress.memoizedState; - if (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); + 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. - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; +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 (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 - ); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + 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 ); - 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. + } - workInProgress.lanes = SomeRetryLane; + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - { - markSpawnedWork(SomeRetryLane); - } + pushSuspenseContext(workInProgress, suspenseContext); - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( - workInProgress, - nextPrimaryChildren, - renderLanes - ); - } + if ((workInProgress.mode & BlockingMode) === 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 { - // This is an update. - // If the current fiber has a SuspenseState, that means it's already showing - // a fallback. - var prevState = current.memoizedState; - - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + switch (revealOrder) { + case "forwards": { + var lastContentRow = findLastContentRow(workInProgress.child); + var tail; - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, + 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, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes + false, // isBackwards + tail, + lastContentRow, + tailMode ); + 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 "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; - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes - ); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - 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 (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes + true, // isBackwards + _tail, + null, // last + tailMode ); + break; + } - 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, + case "together": { + initSuspenseListRenderState( workInProgress, - _nextPrimaryChildren5, - renderLanes + false, // isBackwards + null, // tail + null, // last + undefined ); + break; + } + default: { + // The default reveal order is the same as not having + // a boundary. workInProgress.memoizedState = null; - return _primaryChildFragment6; } } } + + return workInProgress.child; } -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; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + 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); + } + + return workInProgress.child; } -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - if ((mode & BlockingMode) === 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; +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; - 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 (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; + + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); + } } - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); - } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var providerPropTypes = workInProgress.type.propTypes; + + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; + pushProvider(workInProgress, context, newValue); + + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); + + if (changedBits === 0) { + // 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, changedBits, renderLanes); + } + } + + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, 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); -} +var hasWarnedAboutUsingContextAsConsumer = false; + +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 (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; -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren + 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; } - ); - - if ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + var newProps = workInProgress.pendingProps; + var render = newProps.children; - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; + { + 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." + ); + } } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; -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; + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === 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; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - 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 effect during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - var progressedLastEffect = primaryChildFragment.lastEffect; +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; - } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; - } - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); } - var fallbackChildFragment; + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - ); + 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; } 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; + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; } - - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; } -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); - } + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - scheduleWorkOnParentPath(fiber.return, renderLanes); -} + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. -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; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); } - } 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; - } + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); + } } - node = node.return; + 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); } - node.sibling.return = node.return; - node = node.sibling; + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; } } -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 (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - row = row.sibling; + { + 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 + ) + ); + } } - return lastContentRow; -} + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; -function validateRevealOrder(revealOrder) { - { if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - didWarnAboutRevealOrder[revealOrder] = true; + // 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 (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() - ); + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - break; - } + case HostComponent: + pushHostContext(workInProgress); + break; - 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() - ); + case ClassComponent: { + var Component = workInProgress.type; - break; + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); } - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + break; + } - 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; } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - 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; + 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, - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } - } - } -} + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; + break; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; + case SuspenseComponent: { + var state = workInProgress.memoizedState; - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type - ); + 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. - return false; - } - } + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - return true; -} + 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. -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; + 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 { + return null; + } + } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } + + break; } - } else { - var iteratorFn = getIteratorFn(children); - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); + + 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. + + 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; + } - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - _i++; - } + 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; } - } 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 initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - 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) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering - }; + 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; + } + } } 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; - renderState.lastEffect = lastEffectBeforeRendering; - } -} // 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 - ); + 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 (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + workInProgress.lanes = NoLanes; - 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( + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, workInProgress, - workInProgress.child, + workInProgress.type, renderLanes ); } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } - - pushSuspenseContext(workInProgress, suspenseContext); - - if ((workInProgress.mode & BlockingMode) === 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 (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, - workInProgress.lastEffect - ); - break; - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - 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 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 + ); + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); + } - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect - ); - break; - } + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect - ); - break; - } + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } - } - } + case HostText: + return updateHostText(); - return workInProgress.child; -} + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - 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); - } + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - return workInProgress.child; -} + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); + } -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; + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + case Mode: + return updateMode(current, workInProgress, renderLanes); - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var providerPropTypes = workInProgress.type.propTypes; + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); - } - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - pushProvider(workInProgress, newValue); + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); + } + } } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); + + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } -var hasWarnedAboutUsingContextAsConsumer = false; + case IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; -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. + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - { - 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; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes + ); + } - 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; + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + case ScopeComponent: { + break; + } - { - 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 OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); } - } - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } + } { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; +function hadNoMutationsEffects(current, completedWork) { + var didBailout = current !== null && current.child === completedWork.child; + + if (didBailout) { + return true; } - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + 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`. + + var child = completedWork.child; + + while (child !== null) { + if ( + (child.flags & MutationMask) !== NoFlags || + (child.subtreeFlags & MutationMask) !== NoFlags + ) { + return false; + } + + child = child.sibling; } - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + return true; +} + +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; + +{ + // 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; + + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; - 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; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } -} + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + appendInitialChild(parent, _instance); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (newIsHidden) { + var primaryChildParent = node.child; - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } + var fallbackChildParent = primaryChildParent.sibling; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; } + } 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; } - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - var last = returnFiber.lastEffect; + node = node.return; + } - if (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; + node.sibling.return = node.return; + node = node.sibling; } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - current.nextEffect = null; - current.flags = Deletion; - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + 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; - return newWorkInProgress; - } -} + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + 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 (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 - ) - ); - } - } + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance2 = node.stateNode; - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance2 = cloneHiddenTextInstance(); + } - 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. + appendChildToContainerChildSet(containerChildSet, _instance2); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + if (newIsHidden) { + var primaryChildParent = node.child; - case HostComponent: - pushHostContext(workInProgress); - break; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } - case ClassComponent: { - var Component = workInProgress.type; + var fallbackChildParent = primaryChildParent.sibling; - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } } + } - break; + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; } + } 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. - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + node = node; - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; + if (node === workInProgress) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } + }; + + updateHostContainer = function(current, workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); + + 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. + + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); + } + }; - 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, + 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. - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); - break; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - case SuspenseComponent: { - var state = workInProgress.memoizedState; + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - 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 (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); + } - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - 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 newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + workInProgress.stateNode = newInstance; - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + 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); + } + }; - break; - } + 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. - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +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 (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. + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - 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. + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - var renderState = workInProgress.memoizedState; + 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 (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; - } + break; + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + 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 (_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; - } + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; } - 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); - } - } + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - 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 (_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 { - // 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; + // Detach the insertion after the last node that was already + // inserted. + _lastTailNode.sibling = null; } + + break; } - } 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; +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - 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; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - 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. - 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 - ); - } + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + 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. - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); + _child.return = completedWork; + _child = _child.sibling; + } } - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); - - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + 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; + + 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. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; - case HostText: - return updateHostText(); + 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. - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + 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. - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + completedWork.subtreeFlags |= subtreeFlags; + } - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + completedWork.childLanes = newChildLanes; + return didBailout; +} - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); - } +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: case Fragment: - return updateFragment(current, workInProgress, renderLanes); - case Mode: - return updateMode(current, workInProgress, renderLanes); - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + case ContextConsumer: + case MemoComponent: + bubbleProperties(workInProgress); + return null; - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + case ClassComponent: { + var Component = workInProgress.type; - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + if (isContextProvider(Component)) { + popContext(workInProgress); + } - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + bubbleProperties(workInProgress); + return null; + } - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + case HostRoot: { + var fiberRoot = workInProgress.stateNode; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); - } + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } + + 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 (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; } } - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + 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. - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); - } + bubbleProperties(workInProgress); + return null; + } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + 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 _wasHydrated = popHydrationState(); + + 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. + } - case FundamentalComponent: { - break; - } + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - case ScopeComponent: { - break; + bubbleProperties(workInProgress); + return null; } - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + case HostText: { + var newText = newProps; - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); - } - } + 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. - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + 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. + } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} + var _rootContainerInstance = getRootHostContainer(); -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} + var _currentHostContext = getHostContext(); -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + var _wasHydrated2 = popHydrationState(); -{ - // 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; + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + bubbleProperties(workInProgress); + return 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); - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); - } + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + return workInProgress; + } - if (newIsHidden) { - var primaryChildParent = node.child; + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } - var fallbackChildParent = primaryChildParent.sibling; + if (nextDidTimeout && !prevDidTimeout) { + // If this subtree is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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 (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } + 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 (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; + { + // TODO: Only schedule updates if not prevDidTimeout. + if (nextDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. + workInProgress.flags |= Update; } - } 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; } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + bubbleProperties(workInProgress); - node = node.return; + { + 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 doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } + } + } } - node.sibling.return = node.return; - node = node.sibling; + return null; } - }; // 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; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + bubbleProperties(workInProgress); + return null; - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance3 = cloneHiddenTextInstance(); - } + 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; - appendChildToContainerChildSet(containerChildSet, _instance3); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + if (isContextProvider(_Component)) { + popContext(workInProgress); + } + + bubbleProperties(workInProgress); + return null; + } - if (newIsHidden) { - var primaryChildParent = node.child; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - var fallbackChildParent = primaryChildParent.sibling; + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } - } + 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 (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; - } - } 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 (!cannotBeSuspended) { + var row = workInProgress.child; - node = node; + while (row !== null) { + var suspended = findFirstSuspended(row); - if (node === workInProgress) { - return; - } + 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. - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + var newThennables = suspended.updateQueue; - node = node.return; - } + 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. - node.sibling.return = node.return; - node = node.sibling; - } - }; + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - updateHostContainer = function(workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = workInProgress.firstEffect === null; + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - 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. + return workInProgress.child; + } - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + row = row.sibling; + } + } - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; + 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. - 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. + workInProgress.lanes = SomeRetryLane; - var childrenUnchanged = workInProgress.firstEffect === null; + { + markSpawnedWork(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); - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + 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. - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + var _newThennables = _suspended.updateQueue; - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + cutOffTailIfNeeded(renderState, true); // This might have been modified. - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); + 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. - workInProgress.stateNode = newInstance; + workInProgress.lanes = SomeRetryLane; - 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); - } - }; + { + markSpawnedWork(SomeRetryLane); + } + } + } + + 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; - 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 (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; -} + renderState.last = renderedTail; + } + } -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 (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. - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; + var suspenseContext = suspenseStackCursor.current; + + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - 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; + return next; } - break; + bubbleProperties(workInProgress); + return 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; + case ScopeComponent: { + break; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; - 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; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); } - break; + return null; } } -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} +function unwindWork(workInProgress, renderLanes) { switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - return null; - case ClassComponent: { var Component = workInProgress.type; @@ -15163,6 +16187,18 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + return null; } @@ -15170,1935 +16206,2002 @@ function completeWork(current, workInProgress, renderLanes) { popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; + var _flags = workInProgress.flags; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); } - 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(); + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } - 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; + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - updateHostContainer(workInProgress); return null; } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + return null; + } - 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. + case HostPortal: + popHostContainer(workInProgress); + return null; - return null; - } + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + + return null; + + case CacheComponent: + return null; + + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } + + break; + } - 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. + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - var _wasHydrated = popHydrationState(); + case HostComponent: { + popHostContext(interruptedWork); + break; + } - 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. - } + case HostPortal: + popHostContainer(interruptedWork); + break; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - return null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - case HostText: { - var newText = newProps; + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; - 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. + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); - 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. - } + break; + } +} - var _rootContainerInstance = getRootHostContainer(); +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - var _currentHostContext = getHostContext(); +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - var _wasHydrated2 = popHydrationState(); +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - return null; + if (logError === false) { + return; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + var error = errorInfo.value; - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - return workInProgress; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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; + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - 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(); - } - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper + } + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } +} - { - // TODO: Only schedule updates if not prevDidTimeout. - if (nextDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. - workInProgress.flags |= Update; - } - } +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. + + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". + + update.payload = { + element: null + }; + var error = errorInfo.value; - return null; - } + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); + return update; +} - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - return null; + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - return null; + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - 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 inst = fiber.stateNode; - if (isContextProvider(_Component)) { - popContext(workInProgress); + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); } - return null; - } - - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + logCapturedError(fiber, errorInfo); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); - 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 (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } + } + } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - if (!cannotBeSuspended) { - var row = workInProgress.child; + return update; +} - while (row !== null) { - var suspended = findFirstSuspended(row); +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; - 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 (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); - var newThennables = suspended.updateQueue; + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } - 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 list before doing the second pass since that's now invalid. + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); + } +} - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + var tag = sourceFiber.tag; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } + if ( + (sourceFiber.mode & BlockingMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; - row = row.sibling; - } - } + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } - 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 hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. - workInProgress.lanes = SomeRetryLane; + var _workInProgress = returnFiber; - { - markSpawnedWork(SomeRetryLane); - } - } + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; + + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; } 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); + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - 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 ( + (_workInProgress.mode & BlockingMode) === NoMode && + _workInProgress !== returnFiber + ) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - var _newThennables = _suspended.updateQueue; + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - 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. + _workInProgress = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - workInProgress.lanes = SomeRetryLane; + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - { - markSpawnedWork(SomeRetryLane); - } - } - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; - 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; + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - renderState.last = renderedTail; - } + enqueueCapturedUpdate(workInProgress, _update); + return; } - 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.lastEffect = workInProgress.lastEffect; - 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. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - var suspenseContext = suspenseStackCursor.current; + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var _lane = pickArbitraryLane(rootRenderLanes); - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - return next; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - return null; - } + enqueueCapturedUpdate(workInProgress, _update2); + return; + } - case FundamentalComponent: { - break; + break; } - case ScopeComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (current !== null) { - var _nextState = workInProgress.memoizedState; - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; - } - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; - return null; - } - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); + instance.componentWillUnmount(); } -} - -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; +}; // Capture errors so they don't interrupt unmounting. - if (isContextProvider(Component)) { - popContext(workInProgress); - } +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); - var flags = workInProgress.flags; + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); + } + } +} - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; +function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + if (ref !== null) { + if (typeof ref === "function") { + { + { + invokeGuardedCallback(null, ref, null, null); } - return workInProgress; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, refError); + } } - - return null; + } else { + ref.current = null; } + } +} - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; - - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + { + invokeGuardedCallback(null, destroy, null); - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, error); } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber - var _flags2 = workInProgress.flags; + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + var deletions = fiber.deletions; - return workInProgress; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); } - - return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var child = fiber.child; - return null; + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - popProvider(workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - return null; - - default: - return null; } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - break; + resetCurrentFiber(); } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var sibling = fiber.sibling; - case HostComponent: { - popHostContext(interruptedWork); - break; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + nextEffect = fiber.return; + } +} - case ContextProvider: - popProvider(interruptedWork); - break; +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); - break; + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } } -} -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (logError === false) { - return; - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - var error = errorInfo.value; + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 - } + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } + + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + break; + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + case HostRoot: { + break; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + default: { + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); + + resetCurrentFiber(); } } -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } +} -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - update.payload = { - element: null - }; - var error = errorInfo.value; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + if (destroy !== undefined) { + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + } + } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; - - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var inst = fiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + { + var destroy = effect.destroy; - logCapturedError(fiber, errorInfo); - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum ); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes +) { + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); + break; + } + + case ClassComponent: { + var instance = finishedWork.stateNode; + + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } + + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } + + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + + commitUpdateQueue(finishedWork, updateQueue, instance); + } - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } + break; + } - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); - } -} + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes -) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + break; + } - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. - var currentSource = sourceFiber.alternate; + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); + } - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; + break; } - } - - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. - var _workInProgress = returnFiber; + case HostText: { + // We have no life-cycles associated with text. + break; + } - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } + } - if ((_workInProgress.mode & BlockingMode) === NoMode) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + break; + } - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + case SuspenseComponent: { + break; + } - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); - } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. + default: { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } + } - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } +} - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + if (typeof ref === "function") { + { + ref(instanceToUse); + } + } else { + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } + } - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + ref.current = instanceToUse; + } + } +} - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); +function commitDetachRef(current) { + var currentRef = current.ref; - enqueueCapturedUpdate(workInProgress, _update); - return; + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); } + } else { + currentRef.current = null; + } + } +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; +function commitUnmount( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + onCommitUnmount(current); + + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current.updateQueue; - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - var _lane = pickArbitraryLane(rootRenderLanes); + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } + } + } - enqueueCapturedUpdate(workInProgress, _update2); - return; + effect = effect.next; + } while (effect !== firstEffect); } + } - break; + return; } - workInProgress = workInProgress.return; - } while (workInProgress !== null); -} - -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); + } -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + return; + } - { - instance.componentWillUnmount(); - } -}; // Capture errors so they don't interrupt unmounting. + case HostComponent: { + safelyDetachRef(current, nearestMountedAncestor); + return; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + emptyPortalContainer(current); + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + return; } - } -} - -function safelyDetachRef(current) { - var ref = current.ref; - if (ref !== null) { - if (typeof ref === "function") { - { - { - invokeGuardedCallback(null, ref, null, null); - } + case DehydratedFragment: { + return; + } - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); - } - } - } else { - ref.current = null; + case ScopeComponent: { + return; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); +function commitNestedUnmounts( + finishedRoot, + root, + nearestMountedAncestor, + renderPriorityLevel +) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); + while (true) { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. + + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + !supportsMutation + ) { + node.child.return = node; + node = node.child; + continue; } - } -} -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { + if (node === root) { return; } - case ClassComponent: { - if (finishedWork.flags & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + node = node.return; + } - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); + node.sibling.return = node.return; + node = node.sibling; + } +} - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; +function detachFiberMutation(fiber) { + // Cut off the return pointer to disconnect it from the tree. + // This enables us to detect and warn against state updates on an unmounted component. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + fiber.return = null; +} - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); +function detachFiberAfterEffects(fiber) { + // Null out fields to improve GC for references that may be lingering (e.g. DevTools). + // Note that we already cleared the return pointer in detachFiberMutation(). + fiber.alternate = null; + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + { + fiber._debugOwner = null; + } +} - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - } +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: { return; } - case HostRoot: { + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; return; } + } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - return; + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } +} + +function commitDeletion( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + { + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); + } + + var alternate = current.alternate; + detachFiberMutation(current); + + if (alternate !== null) { + detachFiberMutation(alternate); } +} +function commitWork(current, finishedWork) { { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case Profiler: { + return; + } - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } - if (destroy !== undefined) { - destroy(); - } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; } - effect = effect.next; - } while (effect !== firstEffect); + case HostRoot: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + return; + } + } + + commitContainer(finishedWork); + return; } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if (newState !== null) { + markCommitTimeOfFallback(); + } +} - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - { - var destroy = effect.destroy; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum - ); + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); } } - } - - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); + retryCache.add(wakeable); + wakeable.then(retry, retry); } - - effect = next; - } while (effect !== firstEffect); + }); } -} +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - schedulePassiveEffects(finishedWork); - return; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } + } - case ClassComponent: { - var instance = finishedWork.stateNode; + return false; +} - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + nextEffect = firstChild; + commitMutationEffects_begin(root, renderPriorityLevel); +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } +function commitMutationEffects_begin(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + var deletions = fiber.deletions; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber, + renderPriorityLevel + ); - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); } } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + } + } - var updateQueue = finishedWork.updateQueue; + var child = fiber.child; - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root, renderPriorityLevel); + } + } +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. +function commitMutationEffects_complete(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; + + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root, + renderPriorityLevel + ); - commitUpdateQueue(finishedWork, updateQueue, instance); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - return; + resetCurrentFiber(); } - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; + var sibling = fiber.sibling; - if (_updateQueue !== null) { - var _instance = null; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + nextEffect = fiber.return; + } +} - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } +function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { + var flags = finishedWork.flags; - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + if (flags & Ref) { + var current = finishedWork.alternate; - return; + if (current !== null) { + commitDetachRef(current); } + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + var primaryFlags = flags & (Placement | Update | Hydrating); - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); - } + switch (primaryFlags) { + case Placement: { + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. - return; + finishedWork.flags &= ~Placement; + break; } - case HostText: { - // We have no life-cycles associated with text. - return; - } + case PlacementAndUpdate: { + // inserted, before any life-cycles like componentDidMount gets called. - case HostPortal: { - // We have no life-cycles associated with portals. - return; + finishedWork.flags &= ~Placement; // Update + + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; } - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; + } - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } - } + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update - return; + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; } - case SuspenseComponent: { - return; + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; } - - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - return; } +} - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } +function commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } +} - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; - if (typeof ref === "function") { { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } + + resetCurrentFiber(); } + } - ref.current = instanceToUse; + if (fiber === subtreeRoot) { + nextEffect = null; + return; } - } -} -function commitDetachRef(current) { - var currentRef = current.ref; + var sibling = fiber.sibling; - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); + nextEffect = fiber.return; + } +} - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - var updateQueue = current.updateQueue; +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); + } + } +} - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } + if ((fiber.flags & Passive) !== NoFlags) { + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); - effect = effect.next; - } while (effect !== firstEffect); + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - } - - return; - } - - case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + resetCurrentFiber(); } - - return; } - case HostComponent: { - safelyDetachRef(current); + if (fiber === subtreeRoot) { + nextEffect = null; return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); - } + var sibling = fiber.sibling; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - case FundamentalComponent: { - return; - } + nextEffect = fiber.return; + } +} - case DehydratedFragment: { - return; - } +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + } - case ScopeComponent: { - return; + break; } } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - !supportsMutation - ) { - node.child.return = node; - node = node.child; - continue; - } +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; - if (node === root) { - return; - } + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); // Now that passive effects have been processed, it's safe to detach lingering pointers. - node = node.return; - } + var alternate = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); - node.sibling.return = node.return; - node = node.sibling; - } -} + if (alternate !== null) { + detachFiberAfterEffects(alternate); + } + } -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; + nextEffect = fiber; + } + } - { - fiber._debugOwner = null; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); + } } } -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: - case FundamentalComponent: { - return; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); } - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; + var sibling = fiber.sibling; + + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + nextEffect = fiber.return; } } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { +function commitPassiveUnmountOnFiber(finishedWork) { { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current); + finishedWork.flags &= ~PassiveUnmountPendingDev; + var alternate = finishedWork.alternate; + + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; + } } - var alternate = current.alternate; - detachFiberMutation(current); + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } - if (alternate !== null) { - detachFiberMutation(alternate); + break; + } } } -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - return; - } + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag - case Profiler: { - return; - } + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); + } + } +} - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; - } +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; + } - case HostRoot: { - break; - } + var sibling = fiber.sibling; - case OffscreenComponent: - case LegacyHiddenComponent: { - return; - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - commitContainer(finishedWork); - return; + nextEffect = fiber.return; } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (newState !== null) { - markCommitTimeOfFallback(); + break; + } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; - - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); - } - - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } - - retryCache.add(wakeable); - wakeable.then(retry, retry); - } - }); - } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +var didWarnWrongReturnPointer = false; -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { + { + if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { + didWarnWrongReturnPointer = true; - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + error( + "Internal React error: Return pointer is inconsistent " + "with parent." + ); } - } + } // TODO: Remove this assignment once we're confident that it won't break + // anything, by checking the warning logs for the above invariant - return false; + fiber.return = expectedReturnFiber; } var COMPONENT_TYPE = 0; @@ -17180,8 +18283,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -17200,16 +18302,13 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; +var pendingPassiveEffectsRenderPriority = NoPriority; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -17227,13 +18326,10 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17258,63 +18354,41 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + if (currentEventTransitionLane === NoLane) { + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); + return currentEventTransitionLane; } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. + var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be + // the update lane priority, but for now we're also checking for discrete + // updates and falling back to the scheduler priority. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 + schedulerPriority === UserBlockingPriority ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); + lane = findUpdateLane(InputDiscreteLanePriority); } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); + { + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + lane = findUpdateLane(schedulerLanePriority); + } } return lane; @@ -17330,16 +18404,12 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } - - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17412,8 +18482,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) + (priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -17426,13 +18496,9 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. + } - mostRecentlyUpdatedRoot = root; + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17454,7 +18520,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -17483,6 +18549,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // TODO: Optimize slightly by comparing to root that fiber belongs to. + // Requires some refactoring. Not a big deal though since it's rare for + // concurrent apps to have more than a single root. + workInProgressRoot !== null && + (fiber.mode & BlockingMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), + // then don't treat this as an interleaved update. This pattern is + // accompanied by a warning but we haven't fully deprecated it yet. We can + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -17506,22 +18586,36 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var existingCallbackPriority = root.callbackPriority; - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== InputDiscreteLanePriority && + existingCallbackPriority !== SyncLanePriority + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -17530,12 +18624,11 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + newCallbackNode = null; } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority$1, + ImmediatePriority, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -17553,12 +18646,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -17588,24 +18680,22 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; + } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + if (didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); // This will schedule a synchronous callback. + + ensureRootIsScheduled(root, now()); + return null; } var exitStatus = renderRootConcurrent(root, lanes); - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -17797,26 +18887,9 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } } else { - lanes = getNextLanes(root, NoLanes); + lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + exitStatus = renderRootSync(root, lanes); } @@ -17894,7 +18967,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } else { return undefined; } @@ -17950,6 +19023,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; + enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -18273,47 +19347,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18346,9 +19379,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18370,88 +19404,10 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // 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; // 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. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } - } - - completedWork.childLanes = newChildLanes; -} - function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority$1, + ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -18491,7 +19447,8 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -18513,27 +19470,39 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles @@ -18541,62 +19510,22 @@ function commitRootImpl(root, renderPriorityLevel) { ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass // of the effect list for each phase: all mutation effects come before all // layout effects, and so on. - // The first phase a "before mutation" phase. We use this phase to read the - // state of the host tree right before we mutate it. This is where - // getSnapshotBeforeUpdate is called. - - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, renderPriorityLevel, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -18604,29 +19533,8 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); @@ -18656,22 +19564,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -18709,9 +19601,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -18729,9 +19621,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var _error3 = firstUncaughtError; + var error = firstUncaughtError; firstUncaughtError = null; - throw _error3; + throw error; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -18747,149 +19639,14 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - - var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); - - switch (primaryFlags) { - case Placement: { - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } - - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { + if (pendingPassiveEffectsRenderPriority !== NoPriority) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 + pendingPassiveEffectsRenderPriority > NormalPriority + ? NormalPriority : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + pendingPassiveEffectsRenderPriority = NoPriority; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -18898,42 +19655,6 @@ function flushPassiveEffects() { return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -18955,97 +19676,9 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } + var prevInteractions = pushInteractions(root); + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { popInteractions(prevInteractions); @@ -19102,19 +19735,23 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19125,7 +19762,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19135,24 +19772,6 @@ function captureCommitPhaseError(sourceFiber, error) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -19161,6 +19780,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19213,6 +19848,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19381,11 +20018,29 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -19473,14 +20128,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -19666,7 +20330,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -19688,7 +20352,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } finally { @@ -19710,7 +20374,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -19729,11 +20393,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20210,9 +20869,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20339,11 +20997,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20353,8 +21010,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -20411,13 +21070,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -20425,6 +21081,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -20441,7 +21098,12 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; + workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in + // `createWorkInProgress`. Nothing reads this until the complete phase, + // currently, but it might in the future, and we should be consistent. + + workInProgress.subtreeFlags = current.subtreeFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -20468,13 +21130,33 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber(tag, strictModeLevelOverride) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; + mode = ConcurrentMode | BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else { mode = NoMode; } @@ -20525,8 +21207,16 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; - mode |= StrictMode; + fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. + + var level = + pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. + // It is explicitly not supported to lower a mode with nesting, only to increase it. + + if (level >= 1) { + mode |= StrictLegacyMode; + } + break; case REACT_PROFILER_TYPE: @@ -20548,6 +21238,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -20776,9 +21470,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -20845,13 +21538,27 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -20925,7 +21632,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { + if (hostFiber.mode & StrictLegacyMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -20935,7 +21642,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -20974,8 +21681,20 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -21039,7 +21758,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -21579,13 +22303,15 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (componentOrHandle == null) { return null; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle; - } + } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { + // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle.canonical; } @@ -21727,11 +22453,12 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false); + root = createContainer(containerTag, LegacyRoot, false, null, null); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } @@ -21776,8 +22503,8 @@ exports.createPortal = createPortal$1; exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; -exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.render = render; +exports.sendAccessibilityEvent = sendAccessibilityEvent; exports.stopSurface = stopSurface; exports.unmountComponentAtNode = unmountComponentAtNode; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 035c6c10c7b3e8..dc0d1975d80703 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_219 = { +var injectedNamesToPlugins$jscomp$inline_210 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_219 = { } } }, - isOrderingDirty$jscomp$inline_220 = !1, - pluginName$jscomp$inline_221; -for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) + isOrderingDirty$jscomp$inline_211 = !1, + pluginName$jscomp$inline_212; +for (pluginName$jscomp$inline_212 in injectedNamesToPlugins$jscomp$inline_210) if ( - injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( - pluginName$jscomp$inline_221 + injectedNamesToPlugins$jscomp$inline_210.hasOwnProperty( + pluginName$jscomp$inline_212 ) ) { - var pluginModule$jscomp$inline_222 = - injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; + var pluginModule$jscomp$inline_213 = + injectedNamesToPlugins$jscomp$inline_210[pluginName$jscomp$inline_212]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || - namesToPlugins[pluginName$jscomp$inline_221] !== - pluginModule$jscomp$inline_222 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_212) || + namesToPlugins[pluginName$jscomp$inline_212] !== + pluginModule$jscomp$inline_213 ) { - if (namesToPlugins[pluginName$jscomp$inline_221]) + if (namesToPlugins[pluginName$jscomp$inline_212]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_221 + + pluginName$jscomp$inline_212 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_221 - ] = pluginModule$jscomp$inline_222; - isOrderingDirty$jscomp$inline_220 = !0; + pluginName$jscomp$inline_212 + ] = pluginModule$jscomp$inline_213; + isOrderingDirty$jscomp$inline_211 = !0; } } -isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_211 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -996,7 +996,11 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + (from || to).stateNode.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), + to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1020,7 +1024,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1039,6 +1044,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1065,6 +1071,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1098,7 +1106,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1186,19 +1194,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1525,6 +1528,328 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 256; + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1740,296 +2065,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2097,10 +2143,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2151,13 +2197,14 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2183,14 +2230,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2259,111 +2324,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2419,7 +2483,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2430,7 +2495,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2440,7 +2506,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2588,24 +2655,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2637,16 +2702,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2661,7 +2726,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2775,15 +2849,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2816,17 +2882,9 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (existingChildren = existingChildren.get( - null === newChild.key ? newIdx : newChild.key - ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + null === newChild.key ? newIdx : newChild.key + ) || null), + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3032,43 +3090,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3246,7 +3299,7 @@ function findFirstSuspended(row) { 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 & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3398,10 +3451,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3426,22 +3480,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3481,7 +3546,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3511,25 +3576,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3556,6 +3609,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3581,6 +3636,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3629,7 +3686,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3637,10 +3694,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3725,33 +3782,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3808,6 +3887,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -3983,7 +4064,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4059,14 +4140,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4083,30 +4165,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (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 ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, 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.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4116,7 +4207,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4141,7 +4232,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4316,7 +4407,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4324,7 +4415,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4338,7 +4429,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4359,7 +4450,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4403,18 +4494,21 @@ function pushHostRootContext(workInProgress) { 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 & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4431,7 +4525,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4443,9 +4539,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4471,8 +4569,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4499,8 +4600,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4523,7 +4627,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4556,13 +4660,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4572,26 +4677,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4616,8 +4717,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4627,16 +4727,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4645,9 +4743,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4670,7 +4768,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4691,8 +4789,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4714,19 +4811,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4736,25 +4825,33 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - 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; + 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 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, @@ -4871,21 +4968,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4903,15 +5003,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4947,16 +5047,40 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$64 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), + for (var lastTailNode$62 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$64 + null === lastTailNode$62 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$64.sibling = null); + : (lastTailNode$62.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags & 131072), + (subtreeFlags |= child$63.flags & 131072), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + else + for (child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags), + (subtreeFlags |= child$63.flags), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4970,76 +5094,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + 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; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5055,25 +5184,25 @@ function completeWork(current, workInProgress, renderLanes) { "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); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5088,82 +5217,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 131074), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((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 = updatePayload.subtreeFlags), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5174,78 +5313,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5260,8 +5395,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5269,11 +5404,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5281,8 +5416,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5290,10 +5425,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5372,152 +5509,161 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$80 = effect.create; + effect.destroy = create$80(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5526,19 +5672,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5559,7 +5693,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5570,28 +5703,276 @@ function commitWork(current, finishedWork) { ); } } -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); + } +} +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + renderPriorityLevel = root.deletions; + if (null !== renderPriorityLevel) + for ( + firstChild = 0; + firstChild < renderPriorityLevel.length; + firstChild++ + ) { + var childToDelete = renderPriorityLevel[firstChild]; + try { + a: for (var node = childToDelete; ; ) { + var current = node; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, current); + } catch (err) {} + switch (current.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = current.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next, + effect = firstEffect; + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + effect = effect.next; + } while (effect !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(current, root); + var instance = current.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (effect = current), + (_effect = instance), + (_effect.props = effect.memoizedProps), + (_effect.state = effect.memoizedState), + _effect.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + break; + case 5: + safelyDetachRef(current, root); + break; + case 4: + createChildNodeSet(current.stateNode.containerInfo); + } + if (null !== node.child) + (node.child.return = node), (node = node.child); + else { + if (node === childToDelete) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === childToDelete) + break a; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + renderPriorityLevel = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) + (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + var current$jscomp$0 = root.alternate; + if (null !== current$jscomp$0) { + var currentRef = current$jscomp$0.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + renderPriorityLevel = root.sibling; + if (null !== renderPriorityLevel) { + renderPriorityLevel.return = root.return; + nextEffect = renderPriorityLevel; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$81 = firstChild.updateQueue; + if (null !== updateQueue$81) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode.canonical; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$81, current); + } + break; + case 5: + null === current && firstChild.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0.canonical; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; -} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -5603,30 +5984,22 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5636,30 +6009,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5690,7 +6055,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5738,45 +6103,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -5787,16 +6149,22 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); + didTimeout = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus + workInProgressRootRenderLanes !== didTimeout ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); + prepareFreshStack(root, didTimeout); do try { workLoopConcurrent(); @@ -5809,19 +6177,17 @@ function performConcurrentWorkOnRoot(root) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5829,7 +6195,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5839,9 +6205,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -5852,7 +6218,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5860,12 +6226,12 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); prevDispatcher = 1 << index$4; - index$4 = exitStatus[index$4]; + index$4 = didTimeout[index$4]; index$4 > prevExecutionContext && (prevExecutionContext = index$4); lanes &= ~prevDispatcher; } @@ -5912,9 +6278,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } @@ -5922,17 +6288,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -5951,11 +6312,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -5995,7 +6351,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6005,10 +6361,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6044,15 +6419,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6063,15 +6441,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { + var nextState = workInProgress$75.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$75.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6083,16 +6461,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$75.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$75.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$75.mode & 1) && + workInProgress$75 !== returnFiber + ) { + workInProgress$75.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6123,12 +6504,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$75.flags |= 16384; + workInProgress$75.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6137,47 +6518,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$75.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$76 = createRootErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$75, update$76); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$75.type, + instance = workInProgress$75.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$75.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$79 = createClassErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$75, update$79); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6238,47 +6619,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6299,7 +6658,8 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6308,252 +6668,48 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - eventTimes = nextEffect; - a: for (noLongerPendingLanes = expirationTimes = eventTimes; ; ) { - index$10 = noLongerPendingLanes; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, index$10); - } catch (err) {} - switch (index$10.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = index$10.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next; - lane = firstEffect; - do { - var _effect2 = lane, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - index$10, - lane - ); - else { - _effect2 = index$10; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - lane = lane.next; - } while (lane !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(index$10); - var instance = index$10.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (lane = index$10), - (_effect2 = instance), - (_effect2.props = lane.memoizedProps), - (_effect2.state = lane.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(index$10, unmountError); - } - break; - case 5: - safelyDetachRef(index$10); - break; - case 4: - createChildNodeSet(index$10.stateNode.containerInfo); - } - if (null !== noLongerPendingLanes.child) - (noLongerPendingLanes.child.return = noLongerPendingLanes), - (noLongerPendingLanes = noLongerPendingLanes.child); - else { - if (noLongerPendingLanes === expirationTimes) break; - for (; null === noLongerPendingLanes.sibling; ) { - if ( - null === noLongerPendingLanes.return || - noLongerPendingLanes.return === expirationTimes - ) - break a; - noLongerPendingLanes = noLongerPendingLanes.return; - } - noLongerPendingLanes.sibling.return = - noLongerPendingLanes.return; - noLongerPendingLanes = noLongerPendingLanes.sibling; - } - } - var alternate = eventTimes.alternate; - detachFiberMutation(eventTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$87) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$87); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; - requestPaint(); - executionContext = remainingLanes$jscomp$0; - } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes + ? ((remainingLanes = executionContext), + (executionContext |= 32), + (ReactCurrentOwner$2.current = null), + commitBeforeMutationEffects(root, finishedWork), + commitMutationEffects(root, renderPriorityLevel, finishedWork), + (root.current = finishedWork), + commitLayoutEffects(finishedWork, root, lanes), + requestPaint(), + (executionContext = remainingLanes)) + : (root.current = finishedWork); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6564,30 +6720,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6599,24 +6731,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6625,40 +6739,103 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$93 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$93.destroy; - effect$93.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$93 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$97 = effect$93.create; - effect$93.destroy = create$97(); - } catch (error$98) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$98); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (create$97 = root.current.firstEffect; null !== create$97; ) - (root = create$97.nextEffect), - (create$97.nextEffect = null), - create$97.flags & 8 && - ((create$97.sibling = null), (create$97.stateNode = null)), - (create$97 = root); + for (nextEffect = root = root.current; null !== nextEffect; ) + if ( + ((fiber = nextEffect), + (child = fiber.child), + 0 !== (fiber.subtreeFlags & 1040) && null !== child) + ) + (child.return = fiber), (nextEffect = child); + else + a: for (fiber = root; null !== nextEffect; ) { + child = nextEffect; + if (0 !== (child.flags & 1024)) + try { + switch (child.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, child); + } + } catch (error) { + captureCommitPhaseError(child, child.return, error); + } + if (child === fiber) { + nextEffect = null; + break a; + } + deletions = child.sibling; + if (null !== deletions) { + deletions.return = child.return; + nextEffect = deletions; + break a; + } + nextEffect = child.return; + } executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -6673,42 +6850,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6720,7 +6905,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6733,14 +6918,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6756,78 +6940,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - 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.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - 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, + 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, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + 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 ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.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 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 + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -6839,22 +7028,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -6864,8 +7053,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -6876,9 +7065,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -6890,28 +7079,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6920,7 +7109,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6929,7 +7118,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -6938,8 +7127,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -6947,7 +7136,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -6955,32 +7144,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -6991,19 +7180,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7043,16 +7231,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7089,27 +7277,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7121,15 +7303,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7139,20 +7320,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7160,16 +7345,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7177,20 +7362,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7198,28 +7384,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7237,11 +7423,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7251,8 +7437,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7284,8 +7470,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7323,9 +7509,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7360,15 +7546,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7555,7 +7744,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7587,10 +7777,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_865 = { + devToolsConfig$jscomp$inline_914 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7605,11 +7795,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1054 = { - bundleType: devToolsConfig$jscomp$inline_865.bundleType, - version: devToolsConfig$jscomp$inline_865.version, - rendererPackageName: devToolsConfig$jscomp$inline_865.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_865.rendererConfig, +var internals$jscomp$inline_1178 = { + bundleType: devToolsConfig$jscomp$inline_914.bundleType, + version: devToolsConfig$jscomp$inline_914.version, + rendererPackageName: devToolsConfig$jscomp$inline_914.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_914.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7624,7 +7814,7 @@ var internals$jscomp$inline_1054 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_865.findFiberByHostInstance || + devToolsConfig$jscomp$inline_914.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7633,16 +7823,16 @@ var internals$jscomp$inline_1054 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1055 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1179 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1055.isDisabled && - hook$jscomp$inline_1055.supportsFiber + !hook$jscomp$inline_1179.isDisabled && + hook$jscomp$inline_1179.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1055.inject( - internals$jscomp$inline_1054 + (rendererID = hook$jscomp$inline_1179.inject( + internals$jscomp$inline_1178 )), - (injectedHook = hook$jscomp$inline_1055); + (injectedHook = hook$jscomp$inline_1179); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7684,10 +7874,11 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); + var JSCompiler_inline_result = createFiber(3, null, null, 0); + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 51f399468cdf57..96243f376c9204 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_223 = { +var injectedNamesToPlugins$jscomp$inline_216 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ var injectedNamesToPlugins$jscomp$inline_223 = { } } }, - isOrderingDirty$jscomp$inline_224 = !1, - pluginName$jscomp$inline_225; -for (pluginName$jscomp$inline_225 in injectedNamesToPlugins$jscomp$inline_223) + isOrderingDirty$jscomp$inline_217 = !1, + pluginName$jscomp$inline_218; +for (pluginName$jscomp$inline_218 in injectedNamesToPlugins$jscomp$inline_216) if ( - injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( - pluginName$jscomp$inline_225 + injectedNamesToPlugins$jscomp$inline_216.hasOwnProperty( + pluginName$jscomp$inline_218 ) ) { - var pluginModule$jscomp$inline_226 = - injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; + var pluginModule$jscomp$inline_219 = + injectedNamesToPlugins$jscomp$inline_216[pluginName$jscomp$inline_218]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || - namesToPlugins[pluginName$jscomp$inline_225] !== - pluginModule$jscomp$inline_226 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_218) || + namesToPlugins[pluginName$jscomp$inline_218] !== + pluginModule$jscomp$inline_219 ) { - if (namesToPlugins[pluginName$jscomp$inline_225]) + if (namesToPlugins[pluginName$jscomp$inline_218]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_225 + + pluginName$jscomp$inline_218 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_225 - ] = pluginModule$jscomp$inline_226; - isOrderingDirty$jscomp$inline_224 = !0; + pluginName$jscomp$inline_218 + ] = pluginModule$jscomp$inline_219; + isOrderingDirty$jscomp$inline_217 = !0; } } -isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_217 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -997,7 +997,11 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - null !== to + (from || to).stateNode.canonical._internalInstanceHandle + ? (from && + nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), + to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) + : null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1021,7 +1025,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1040,6 +1045,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1066,6 +1072,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1099,7 +1107,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1187,19 +1195,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1526,6 +1529,342 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 256; + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$7 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$7; + remainingLanes[index$7] = 0; + eventTimes[index$7] = -1; + root[index$7] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$8 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$8; + (lane & entangledLanes) | (root[index$8] & entangledLanes) && + (root[index$8] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -1742,310 +2081,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { } var rendererID = null, injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, priorityLevel) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2113,10 +2159,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue2 = currentValue; + context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2167,13 +2213,14 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2199,14 +2246,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2275,111 +2340,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2435,7 +2499,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2446,7 +2511,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2456,7 +2522,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2604,24 +2671,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2653,16 +2718,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2677,7 +2742,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2789,17 +2863,9 @@ function ChildReconciler(shouldTrackSideEffects) { : updateTextNode(returnFiber, oldFiber, "" + newChild, lanes); if ("object" === typeof newChild && null !== newChild) { switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + case REACT_ELEMENT_TYPE: + return newChild.key === key + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2834,15 +2900,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3048,43 +3106,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3262,7 +3315,7 @@ function findFirstSuspended(row) { 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 & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3414,10 +3467,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3442,22 +3496,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3497,7 +3562,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3527,25 +3592,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$11 = 31 - clz32(lanes), - lane = 1 << index$11; - entanglements[index$11] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3572,6 +3625,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3597,6 +3652,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3645,7 +3702,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3653,10 +3710,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3741,33 +3798,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3824,6 +3903,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4014,7 +4095,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4090,14 +4171,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4114,31 +4196,40 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, 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.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4148,7 +4239,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4173,7 +4264,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4348,7 +4439,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4356,7 +4447,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4370,7 +4461,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4391,7 +4482,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4439,18 +4530,21 @@ function pushHostRootContext(workInProgress) { 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 & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4467,7 +4561,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4479,10 +4575,12 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4508,8 +4606,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4536,8 +4637,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4560,10 +4664,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 4 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4598,13 +4702,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4614,33 +4719,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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 & 8 && + workInProgress.mode & 4 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4665,8 +4764,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4676,16 +4774,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4694,9 +4790,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4719,7 +4815,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4740,8 +4836,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4763,19 +4858,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4786,25 +4873,33 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - 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; + 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 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, @@ -4921,21 +5016,24 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(workInProgress) { +updateHostContainer = function(current, workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (null !== workInProgress.firstEffect) { - var container = portalOrRoot.containerInfo, - newChildSet = createChildNodeSet(container); + if (!hadNoMutationsEffects(current, workInProgress)) { + current = portalOrRoot.containerInfo; + var newChildSet = createChildNodeSet(current); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(container, newChildSet); + completeRoot(current, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ((current = null === workInProgress.firstEffect) && oldProps === newProps) + if ( + (current = hadNoMutationsEffects(current, workInProgress)) && + oldProps === newProps + ) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -4953,15 +5051,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (recyclableInstance = type.node), + (oldProps = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(recyclableInstance, newProps) - : cloneNode(recyclableInstance) + ? cloneNodeWithNewProps(oldProps, newProps) + : cloneNode(oldProps) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) - : cloneNodeWithNewChildren(recyclableInstance), + ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) + : cloneNodeWithNewChildren(oldProps), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -4997,16 +5095,76 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$65 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$65 + null === lastTailNode$63 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$65.sibling = null); + : (lastTailNode$63.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 & 4)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 131072), + (subtreeFlags |= child$66.flags & 131072), + (treeBaseDuration$65 += child$66.treeBaseDuration), + (child$66 = child$66.sibling); + completedWork.treeBaseDuration = treeBaseDuration$65; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 131072), + (subtreeFlags |= treeBaseDuration$65.flags & 131072), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 4)) { + treeBaseDuration$65 = completedWork.actualDuration; + child$66 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$65 += child.actualDuration), + (child$66 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$65; + completedWork.treeBaseDuration = child$66; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags), + (subtreeFlags |= treeBaseDuration$65.flags), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -5020,76 +5178,81 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + 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; - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); - rootContainerInstance = createNode( + renderLanes = createNode( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - renderLanes, + type, newProps, workInProgress ); - current = { node: rootContainerInstance, canonical: current }; + current = { node: renderLanes, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 128); + null !== workInProgress.ref && (workInProgress.flags |= 256); } + bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5105,30 +5268,30 @@ function completeWork(current, workInProgress, renderLanes) { "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); - rootContainerInstance = requiredContext(contextStackCursor$1.current); + renderLanes = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - rootContainerInstance, + renderLanes, workInProgress ); } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5143,89 +5306,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 4) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 131074), + (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 = type.subtreeFlags), + (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 }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5235,80 +5409,76 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5323,9 +5493,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5335,11 +5505,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5347,9 +5517,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null @@ -5359,10 +5529,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5441,164 +5613,161 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode.canonical; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$84 = effect.create; + effect.destroy = create$84(); } - return; - case 5: - null === current && finishedWork.flags & 4 && shim(); - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5607,19 +5776,7 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedWork = current = current.next; - do { - if (3 === (finishedWork.tag & 3)) { - var destroy = finishedWork.destroy; - finishedWork.destroy = void 0; - void 0 !== destroy && destroy(); - } - finishedWork = finishedWork.next; - } while (finishedWork !== current); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 12: return; @@ -5640,7 +5797,6 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: - case 20: break a; case 3: case 4: @@ -5668,13 +5824,284 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + renderPriorityLevel = root.deletions; + if (null !== renderPriorityLevel) + for ( + firstChild = 0; + firstChild < renderPriorityLevel.length; + firstChild++ + ) { + var childToDelete = renderPriorityLevel[firstChild]; + try { + a: for (var node = childToDelete; ; ) { + var current = node; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, current); + } catch (err) {} + switch (current.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = current.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next, + effect = firstEffect; + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + if (void 0 !== destroy && 0 !== (tag & 2)) { + _effect = current; + var nearestMountedAncestor = root; + try { + destroy(); + } catch (error) { + captureCommitPhaseError( + _effect, + nearestMountedAncestor, + error + ); + } + } + effect = effect.next; + } while (effect !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(current, root); + var instance = current.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (effect = current), + (_effect = instance), + (_effect.props = effect.memoizedProps), + (_effect.state = effect.memoizedState), + _effect.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(current, root, unmountError); + } + break; + case 5: + safelyDetachRef(current, root); + break; + case 4: + createChildNodeSet(current.stateNode.containerInfo); + } + if (null !== node.child) + (node.child.return = node), (node = node.child); + else { + if (node === childToDelete) break; + for (; null === node.sibling; ) { + if (null === node.return || node.return === childToDelete) + break a; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } + } + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, root, error); + } + } + renderPriorityLevel = root.child; + if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) + (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var flags = root.flags; + if (flags & 256) { + var current$jscomp$0 = root.alternate; + if (null !== current$jscomp$0) { + var currentRef = current$jscomp$0.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + root.flags &= -3; + break; + case 6: + root.flags &= -3; + commitWork(root.alternate, root); + break; + case 2048: + root.flags &= -2049; + break; + case 2052: + root.flags &= -2049; + commitWork(root.alternate, root); + break; + case 4: + commitWork(root.alternate, root); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + renderPriorityLevel = root.sibling; + if (null !== renderPriorityLevel) { + renderPriorityLevel.return = root.return; + nextEffect = renderPriorityLevel; + break; + } + nextEffect = root.return; + } + } +} +function commitLayoutEffects(finishedWork, root) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + if (0 !== (fiber$jscomp$0.flags & 324)) { + var current = fiber$jscomp$0.alternate; + try { + var finishedRoot = firstChild; + if (0 !== (fiber$jscomp$0.flags & 68)) + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, fiber$jscomp$0); + break; + case 1: + var instance = fiber$jscomp$0.stateNode; + if (fiber$jscomp$0.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + fiber$jscomp$0.elementType === fiber$jscomp$0.type + ? current.memoizedProps + : resolveDefaultProps( + fiber$jscomp$0.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = fiber$jscomp$0.updateQueue; + null !== updateQueue && + commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + break; + case 3: + var updateQueue$85 = fiber$jscomp$0.updateQueue; + if (null !== updateQueue$85) { + finishedRoot = null; + if (null !== fiber$jscomp$0.child) + switch (fiber$jscomp$0.child.tag) { + case 5: + finishedRoot = + fiber$jscomp$0.child.stateNode.canonical; + break; + case 1: + finishedRoot = fiber$jscomp$0.child.stateNode; + } + commitUpdateQueue( + fiber$jscomp$0, + updateQueue$85, + finishedRoot + ); + } + break; + case 5: + null === current && fiber$jscomp$0.flags & 4 && shim(); + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = fiber$jscomp$0.memoizedProps.onRender, + commitTime$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + fiber$jscomp$0.memoizedProps.id, + current, + fiber$jscomp$0.actualDuration, + fiber$jscomp$0.treeBaseDuration, + fiber$jscomp$0.actualStartTime, + commitTime$88, + finishedRoot.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (fiber$jscomp$0.flags & 256) { + finishedRoot = void 0; + var ref = fiber$jscomp$0.ref; + if (null !== ref) { + var instance$jscomp$0 = fiber$jscomp$0.stateNode; + switch (fiber$jscomp$0.tag) { + case 5: + finishedRoot = instance$jscomp$0.canonical; + break; + default: + finishedRoot = instance$jscomp$0; + } + "function" === typeof ref + ? ref(finishedRoot) + : (ref.current = finishedRoot); + } + } + } catch (error) { + captureCommitPhaseError( + fiber$jscomp$0, + fiber$jscomp$0.return, + error + ); + } + } + if (fiber$jscomp$0 === fiber) { + nextEffect = null; + break; + } + finishedRoot = fiber$jscomp$0.sibling; + if (null !== finishedRoot) { + finishedRoot.return = fiber$jscomp$0.return; + nextEffect = finishedRoot; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -5687,14 +6114,11 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -5702,17 +6126,12 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5722,30 +6141,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5778,7 +6189,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -5826,45 +6237,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -5875,8 +6283,14 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; + didTimeout = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -5898,21 +6312,19 @@ function performConcurrentWorkOnRoot(root) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; + executionContext = didTimeout; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -5920,7 +6332,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -5930,9 +6342,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -5943,7 +6355,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -5951,12 +6363,12 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); lanes$jscomp$0 = 1 << index$4; - index$4 = exitStatus[index$4]; + index$4 = didTimeout[index$4]; index$4 > prevDispatcher && (prevDispatcher = index$4); lanes &= ~lanes$jscomp$0; } @@ -6003,9 +6415,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$9 = 31 - clz32(suspendedLanes), - lane = 1 << index$9; - root[index$9] = -1; + var index$6 = 31 - clz32(suspendedLanes), + lane = 1 << index$6; + root[index$6] = -1; suspendedLanes &= ~lane; } } @@ -6013,17 +6425,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6042,11 +6449,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6086,7 +6488,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6096,10 +6498,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6130,7 +6551,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 4 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6138,15 +6559,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6157,15 +6581,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { + var nextState = workInProgress$79.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$79.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6177,16 +6601,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$79.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$79.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$79.mode & 1) && + workInProgress$79 !== returnFiber + ) { + workInProgress$79.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6217,12 +6644,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$79.flags |= 16384; + workInProgress$79.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6231,47 +6658,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$79.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$80 = createRootErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$79, update$80); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$79.type, + instance = workInProgress$79.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$79.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$83 = createClassErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$79, update$83); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6330,7 +6757,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 4) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6347,8 +6774,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 4)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6361,65 +6788,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 4)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6427,8 +6803,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6459,271 +6836,65 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$10 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$10; - remainingLanes$jscomp$0[index$10] = 0; - eventTimes[index$10] = -1; - expirationTimes[index$10] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = executionContext; executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + var prevInteractions = pushInteractions(root); + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - nextEffect.flags &= -3; - break; - case 6: - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - a: for (index$10 = noLongerPendingLanes = expirationTimes; ; ) { - lane = index$10; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, lane); - } catch (err) {} - switch (lane.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = lane.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (tag & 4)) - enqueuePendingPassiveHookEffectUnmount( - lane, - effect - ); - else { - _effect2 = lane; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } - } - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(lane); - var instance = lane.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = lane), - (_effect2 = instance), - (_effect2.props = effect.memoizedProps), - (_effect2.state = effect.memoizedState), - _effect2.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(lane, unmountError); - } - break; - case 5: - safelyDetachRef(lane); - break; - case 4: - createChildNodeSet(lane.stateNode.containerInfo); - } - if (null !== index$10.child) - (index$10.child.return = index$10), - (index$10 = index$10.child); - else { - if (index$10 === noLongerPendingLanes) break; - for (; null === index$10.sibling; ) { - if ( - null === index$10.return || - index$10.return === noLongerPendingLanes - ) - break a; - index$10 = index$10.return; - } - index$10.sibling.return = index$10.return; - index$10 = index$10.sibling; - } - } - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$90) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$90); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, renderPriorityLevel, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance$jscomp$0 = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + tracing.__interactionsRef.current = prevInteractions; + executionContext = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) + if ((prevInteractions = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance$jscomp$0 = nextEffect), - (instance$jscomp$0.sibling = null), - (instance$jscomp$0.stateNode = null)), - (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance$jscomp$0 = 0; - instance$jscomp$0 < ref.length; - instance$jscomp$0++ - ) + if (null !== spawnedWorkDuringRender) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) scheduleInteractions( root, - ref[instance$jscomp$0], + expirationTimes[i], root.memoizedInteractions ); + } schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + prevInteractions || finishPendingInteractions(root, lanes); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6734,30 +6905,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6769,24 +6916,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -6797,41 +6926,104 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$96 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$96.destroy; - effect$96.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + var prevInteractions = pushInteractions(root); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$96 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$100 = effect$96.create; - effect$96.destroy = create$100(); - } catch (error$101) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$101); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$100 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$100); + for (nextEffect = fiber = root.current; null !== nextEffect; ) + if ( + ((child = nextEffect), + (deletions = child.child), + 0 !== (child.subtreeFlags & 1040) && null !== deletions) + ) + (deletions.return = child), (nextEffect = deletions); + else + a: for (child = fiber; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break a; + } + i = deletions.sibling; + if (null !== i) { + i.return = deletions.return; + nextEffect = i; + break a; + } + nextEffect = deletions.return; + } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -6849,43 +7041,51 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), + schedulePendingInteractions(nearestMountedAncestor, 1)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6897,7 +7097,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6911,14 +7111,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6935,85 +7134,90 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - 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.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue2); - context._currentValue2 = updateLanes; - 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, + 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, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + 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 ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.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 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 + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7025,22 +7229,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7050,8 +7254,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7062,9 +7266,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7076,28 +7280,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7106,7 +7310,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7115,7 +7319,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7124,8 +7328,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7133,7 +7337,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7141,32 +7345,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7177,19 +7381,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7229,16 +7432,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7279,27 +7482,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue2); - context$jscomp$0._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue2); + updateLanes._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7311,15 +7508,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7329,20 +7525,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7350,16 +7550,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7367,20 +7567,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7388,28 +7589,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7427,11 +7628,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7441,8 +7642,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7543,9 +7744,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$102) { + } catch (error$95) { scheduleCallback(99, function() { - throw error$102; + throw error$95; }); } })); @@ -7561,8 +7762,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7603,11 +7804,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7644,15 +7845,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7843,7 +8047,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7875,10 +8080,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_887 = { + devToolsConfig$jscomp$inline_941 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7893,11 +8098,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1087 = { - bundleType: devToolsConfig$jscomp$inline_887.bundleType, - version: devToolsConfig$jscomp$inline_887.version, - rendererPackageName: devToolsConfig$jscomp$inline_887.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_887.rendererConfig, +var internals$jscomp$inline_1218 = { + bundleType: devToolsConfig$jscomp$inline_941.bundleType, + version: devToolsConfig$jscomp$inline_941.version, + rendererPackageName: devToolsConfig$jscomp$inline_941.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_941.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7912,7 +8117,7 @@ var internals$jscomp$inline_1087 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_887.findFiberByHostInstance || + devToolsConfig$jscomp$inline_941.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7921,16 +8126,16 @@ var internals$jscomp$inline_1087 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1088 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1219 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1088.isDisabled && - hook$jscomp$inline_1088.supportsFiber + !hook$jscomp$inline_1219.isDisabled && + hook$jscomp$inline_1219.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1088.inject( - internals$jscomp$inline_1087 + (rendererID = hook$jscomp$inline_1219.inject( + internals$jscomp$inline_1218 )), - (injectedHook = hook$jscomp$inline_1088); + (injectedHook = hook$jscomp$inline_1219); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7973,7 +8178,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); + isDevToolsPresent && (JSCompiler_inline_result |= 4); JSCompiler_inline_result = createFiber( 3, null, @@ -7982,6 +8187,7 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 6b9ea503d3866e..96a631c87dd349 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; -var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; +var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2864,12 +2864,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; -var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; +var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2885,12 +2885,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); - REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2964,6 +2964,9 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + + case REACT_CACHE_TYPE: + return "Cache"; } if (typeof type === "object") { @@ -3001,9 +3004,10 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; -var enableFundamentalAPI = false; +var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; +var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -3021,53 +3025,84 @@ var Update = 4; var PlacementAndUpdate = /* */ - 6; -var Deletion = - /* */ - 8; + Placement | Update; +var ChildDeletion = + /* */ + 16; var ContentReset = /* */ - 16; + 32; var Callback = /* */ - 32; + 64; var DidCapture = /* */ - 64; + 128; var Ref = /* */ - 128; + 256; var Snapshot = /* */ - 256; + 512; var Passive = /* */ - 512; + 1024; var Hydrating = /* */ - 1024; + 2048; var HydratingAndUpdate = /* */ - 1028; + Hydrating | Update; +var Visibility = + /* */ + 4096; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 4095; // These are not really side effects, but we still reuse this field. + 8191; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 4096; + 8192; var ShouldCapture = /* */ - 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 16384; + 32768; var ForceUpdateForLegacySuspense = /* */ - 32768; // Static tags describe aspects of a fiber that are not specific to a render, + 65536; // Static tags describe aspects of a fiber that are not specific to a render, +// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). +// This enables us to defer more work in the unmount case, +// since we can defer traversing the tree during layout to look for Passive effects, +// and instead rely on the static flag as a signal that there may be cleanup work. + +var PassiveStatic = + /* */ + 131072; // These flags allow us to traverse to fibers that have effects on mount +// don't contain effects, by checking subtreeFlags. + +var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity + // flag logic (see #20043) + Update | Snapshot | 0; +var MutationMask = + Placement | + Update | + ChildDeletion | + ContentReset | + Ref | + Hydrating | + Visibility; +var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask + +var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. +// This allows certain concepts to persist without recalculting them, +// e.g. whether a subtree contains passive effects or portals. + +var StaticMask = PassiveStatic; var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3307,38 +3342,28 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); + return currentParent !== null + ? findCurrentHostFiberImpl(currentParent) + : null; +} - if (!currentParent) { - return null; - } // Next we'll drill down this component to find the first HostComponent/Text. - - var node = currentParent; - - while (true) { - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } else if (node.child) { - node.child.return = node; - node = node.child; - continue; - } +function findCurrentHostFiberImpl(node) { + // Next we'll drill down this component to find the first HostComponent/Text. + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } - if (node === currentParent) { - return null; - } + var child = node.child; - while (!node.sibling) { - if (!node.return || node.return === currentParent) { - return null; - } + while (child !== null) { + var match = findCurrentHostFiberImpl(child); - node = node.return; + if (match !== null) { + return match; } - node.sibling.return = node.return; - node = node.sibling; - } // Flow needs the return null here, but ESLint complains about it. - // eslint-disable-next-line no-unreachable + child = child.sibling; + } return null; } @@ -3959,2090 +3984,2139 @@ var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { return ReactNativeFiberHostComponent; })(); // eslint-disable-next-line no-unused-expressions -// can re-export everything from this module. +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -function shim() { - { +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" ); } -} // Hydration (when unsupported) -var isSuspenseInstancePending = shim; -var isSuspenseInstanceFallback = shim; -var hydrateTextInstance = shim; +} -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; -var UPDATE_SIGNAL = {}; +// Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. -{ - Object.freeze(UPDATE_SIGNAL); -} // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. +var NoPriority = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. -var nextReactTag = 3; +var now = + initialTimeMs < 10000 + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority; -function allocateTag() { - var tag = nextReactTag; + case Scheduler_UserBlockingPriority: + return UserBlockingPriority; - if (tag % 10 === 1) { - tag += 2; - } + case Scheduler_NormalPriority: + return NormalPriority; - nextReactTag = tag + 2; - return tag; -} + case Scheduler_LowPriority: + return LowPriority; -function recursivelyUncacheFiberNode(node) { - if (typeof node === "number") { - // Leaf node (eg text) - uncacheFiberNode(node); - } else { - uncacheFiberNode(node._nativeTag); + case Scheduler_IdlePriority: + return IdlePriority; - node._children.forEach(recursivelyUncacheFiberNode); + default: { + throw Error("Unknown priority level."); + } } } -function appendInitialChild(parentInstance, child) { - parentInstance._children.push(child); -} -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = allocateTag(); - var viewConfig = getViewConfigForType(type); - { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority: + return Scheduler_ImmediatePriority; + + case UserBlockingPriority: + return Scheduler_UserBlockingPriority; + + case NormalPriority: + return Scheduler_NormalPriority; + + case LowPriority: + return Scheduler_LowPriority; + + case IdlePriority: + return Scheduler_IdlePriority; + + default: { + throw Error("Unknown priority level."); } } +} - var updatePayload = create(props, viewConfig.validAttributes); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload // props - ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); - precacheFiberNode(internalInstanceHandle, tag); - updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined - // in the same file but if it's external it can't see the types. +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we + // forget to explicitly flush. - return component; + { + // Flush the queue in the next tick. + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); + } + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); + } } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); +function cancelCallback(callbackNode) { + Scheduler_cancelCallback(callbackNode); +} +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); } - var tag = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - } // props - ); - precacheFiberNode(internalInstanceHandle, tag); - return tag; + flushSyncCallbackQueueImpl(); } -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - // Don't send a no-op message over the bridge. - if (parentInstance._children.length === 0) { - return false; - } // Map from child objects to native tags. - // Either way we need to pass a copy of the Array to prevent it from being frozen. - var nativeTags = parentInstance._children.map(function(child) { - return typeof child === "number" - ? child // Leaf node (eg text) - : child._nativeTag; - }); +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, // containerTag - nativeTags // reactTags - ); - return false; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; + { + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; - } -} -function getPublicInstance(instance) { - return instance; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - return UPDATE_SIGNAL; -} -function resetAfterCommit(containerInfo) { - // Noop -} -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} // ------------------- -function appendChild(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - var children = parentInstance._children; - var index = children.indexOf(child); + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick - if (index >= 0) { - children.splice(index, 1); - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [index], // moveFromIndices - [children.length - 1], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [children.length - 1], // addAtIndices - [] // removeAtIndices - ); + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ); + throw error; + } finally { + isFlushingSyncQueue = false; + } + } } } -function appendChildToContainer(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance, // containerTag - [childTag] // reactTags - ); -} -function commitTextUpdate(textInstance, oldText, newText) { - ReactNativePrivateInterface.UIManager.updateView( - textInstance, // reactTag - "RCTRawText", // viewName - { - text: newText - } // props - ); -} -function commitUpdate( - instance, - updatePayloadTODO, - type, - oldProps, - newProps, - internalInstanceHandle -) { - var viewConfig = instance.viewConfig; - updateFiberProps(instance._nativeTag, newProps); - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. - if (updatePayload != null) { - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, // reactTag - viewConfig.uiViewClassName, // viewName - updatePayload // props - ); +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. +// If those values are changed that package should be rebuilt and redeployed. + +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLane = + /* */ + 8; +var InputContinuousHydrationLane = + /* */ + 16; +var InputContinuousLane = + /* */ + 32; +var DefaultHydrationLane = + /* */ + 64; +var DefaultLane = + /* */ + 128; +var TransitionHydrationLane = + /* */ + 256; +var TransitionLanes = + /* */ + 8388096; +var TransitionLane1 = + /* */ + 512; +var TransitionLane2 = + /* */ + 1024; +var TransitionLane3 = + /* */ + 2048; +var TransitionLane4 = + /* */ + 4096; +var TransitionLane5 = + /* */ + 8192; +var TransitionLane6 = + /* */ + 16384; +var TransitionLane7 = + /* */ + 32768; +var TransitionLane8 = + /* */ + 65536; +var TransitionLane9 = + /* */ + 131072; +var TransitionLane10 = + /* */ + 262144; +var TransitionLane11 = + /* */ + 524288; +var TransitionLane12 = + /* */ + 1048576; +var TransitionLane13 = + /* */ + 2097152; +var TransitionLane14 = + /* */ + 4194304; +var RetryLanes = + /* */ + 125829120; +var RetryLane1 = + /* */ + 8388608; +var RetryLane2 = + /* */ + 16777216; +var RetryLane3 = + /* */ + 33554432; +var RetryLane4 = + /* */ + 67108864; +var SomeRetryLane = RetryLane1; +var SelectiveHydrationLane = + /* */ + 134217728; +var NonIdleLanes = + /* */ + 268435455; +var IdleHydrationLane = + /* */ + 268435456; +var IdleLane = + /* */ + 536870912; +var OffscreenLane = + /* */ + 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) +var NoTimestamp = -1; +var nextTransitionLane = TransitionLane1; +var nextRetryLane = RetryLane1; +// Used by getHighestPriorityLanes and getNextLanes: + +var return_highestLanePriority = DefaultLanePriority; + +function getHighestPriorityLanes(lanes) { + switch (getHighestPriorityLane(lanes)) { + case SyncLane: + return_highestLanePriority = SyncLanePriority; + return SyncLane; + + case SyncBatchedLane: + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; + + case InputDiscreteHydrationLane: + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; + + case InputDiscreteLane: + return_highestLanePriority = InputDiscreteLanePriority; + return InputDiscreteLane; + + case InputContinuousHydrationLane: + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; + + case InputContinuousLane: + return_highestLanePriority = InputContinuousLanePriority; + return InputContinuousLane; + + case DefaultHydrationLane: + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + + case DefaultLane: + return_highestLanePriority = DefaultLanePriority; + return DefaultLane; + + case TransitionHydrationLane: + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + + case TransitionLane1: + case TransitionLane2: + case TransitionLane3: + case TransitionLane4: + case TransitionLane5: + case TransitionLane6: + case TransitionLane7: + case TransitionLane8: + case TransitionLane9: + case TransitionLane10: + case TransitionLane11: + case TransitionLane12: + case TransitionLane13: + case TransitionLane14: + return_highestLanePriority = TransitionPriority; + return lanes & TransitionLanes; + + case RetryLane1: + case RetryLane2: + case RetryLane3: + case RetryLane4: + return_highestLanePriority = RetryLanePriority; + return lanes & RetryLanes; + + case SelectiveHydrationLane: + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + + case IdleHydrationLane: + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + + case IdleLane: + return_highestLanePriority = IdleLanePriority; + return IdleLane; + + case OffscreenLane: + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; + + default: + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + + return_highestLanePriority = DefaultLanePriority; + return lanes; } } -function insertBefore(parentInstance, child, beforeChild) { - var children = parentInstance._children; - var index = children.indexOf(child); // Move existing child or add new child? - if (index >= 0) { - children.splice(index, 1); - var beforeChildIndex = children.indexOf(beforeChild); - children.splice(beforeChildIndex, 0, child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [index], // moveFromIndices - [beforeChildIndex], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - var _beforeChildIndex = children.indexOf(beforeChild); - - children.splice(_beforeChildIndex, 0, child); - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [_beforeChildIndex], // addAtIndices - [] // removeAtIndices - ); - } -} -function insertInContainerBefore(parentInstance, child, beforeChild) { - // TODO (bvaughn): Remove this check when... - // We create a wrapper object for the container in ReactNative render() - // Or we refactor to remove wrapper objects entirely. - // For more info on pros/cons see PR #8560 description. - if (!(typeof parentInstance !== "number")) { - throw Error("Container does not support insertBefore operation"); - } -} -function removeChild(parentInstance, child) { - recursivelyUncacheFiberNode(child); - var children = parentInstance._children; - var index = children.indexOf(child); - children.splice(index, 1); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [index] // removeAtIndices - ); -} -function removeChildFromContainer(parentInstance, child) { - recursivelyUncacheFiberNode(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [0] // removeAtIndices - ); -} -function resetTextContent(instance) { - // Noop -} -function hideInstance(instance) { - var viewConfig = instance.viewConfig; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function hideTextInstance(textInstance) { - throw new Error("Not yet implemented."); -} -function unhideInstance(instance, props) { - var viewConfig = instance.viewConfig; - var updatePayload = diff( - Object.assign({}, props, { - style: [ - props.style, - { - display: "none" - } - ] - }), - props, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function clearContainer(container) { - // TODO Implement this for React Native - // UIManager does not expose a "remove all" type method. -} -function unhideTextInstance(textInstance, text) { - throw new Error("Not yet implemented."); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} - -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; - -function disabledLog() {} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + case UserBlockingPriority: + return InputContinuousLanePriority; - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ - } + case IdlePriority: + return IdleLanePriority; - disabledDepth++; + default: + return NoLanePriority; } } -function reenableLogs() { - { - disabledDepth--; +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); - } - } -} + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; + case NoLanePriority: + return NoPriority; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; + default: { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } - - return describeComponentFrame(name, source, ownerName); } } -var componentFrameCache; +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; + } -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". + if (expiredLanes !== NoLanes) { + // TODO: Should entangle with SyncLane + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - if (match) { - var pathBeforeSlash = match[1]; + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; } } - } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } + } + } } - return "\n in " + (name || "Unknown") + sourceInfo; -} + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); - } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; + + if ( + nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The + // only difference between default updates and transition updates is that + // default updates do not support refresh transitions. + (nextLanePriority === DefaultLanePriority && + wipLanePriority === TransitionPriority) + ) { + // Keep working on the existing in-progress tree. Do not interrupt. + return wipLanes; + } else { + return_highestLanePriority = nextLanePriority; } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // TODO: Reconsider this. The counter-argument is that the partial work + // represents an intermediate state, which we don't want to show to the user. + // And by spending extra time finishing it, we're increasing the amount of + // time it takes to show the final state, which is what they are actually + // waiting for. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - var name = fn.displayName || fn.name || null; - var ownerName = null; + var entangledLanes = root.entangledLanes; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - return describeComponentFrame(name, source, ownerName); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; + } } + + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - } - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); + lanes &= ~lane; } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + return mostRecentEventTime; +} - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; + + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; } +} - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + var lanes = pendingLanes; - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - } - return ""; -} + lanes &= ~lane; + } +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); - } + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } -} -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; +} +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} +function isTransitionLane(lane) { + return (lane & TransitionLanes) !== 0; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case NoLanePriority: + break; - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } + case SyncLanePriority: + return SyncLane; - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } + case SyncBatchedLanePriority: + return SyncBatchedLane; - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); + case InputDiscreteLanePriority: + return InputDiscreteLane; - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); + case InputContinuousLanePriority: + return InputContinuousLane; - setCurrentlyValidatingElement(null); - } + case DefaultLanePriority: + return DefaultLane; - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + case TransitionPriority: // Should be handled by findTransitionLane instead - error("Failed %s type: %s", location, error$1.message); + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; - setCurrentlyValidatingElement(null); - } - } - } + case IdleLanePriority: + return IdleLane; } -} -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; + { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } } +function claimNextTransitionLane() { + // Cycle through the lanes, assigning each new transition to the next lane. + // In most cases, this means every transition gets its own lane, until we + // run out of lanes and cycle back to the beginning. + var lane = nextTransitionLane; + nextTransitionLane <<= 1; -var index = -1; + if ((nextTransitionLane & TransitionLanes) === 0) { + nextTransitionLane = TransitionLane1; + } -function createCursor(defaultValue) { - return { - current: defaultValue - }; + return lane; } +function claimNextRetryLane() { + var lane = nextRetryLane; + nextRetryLane <<= 1; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } - - return; - } - - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } + if ((nextRetryLane & RetryLanes) === 0) { + nextRetryLane = RetryLane1; } - cursor.current = valueStack[index]; - valueStack[index] = null; - - { - fiberStack[index] = null; - } + return lane; +} - index--; +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - { - fiberStack[index] = fiber; - } +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); +} - cursor.current = value; +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); } -var warnedAboutMissingGetChildContext; +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} +function intersectLanes(a, b) { + return a & b; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). -{ - warnedAboutMissingGetChildContext = {}; +function laneToLanes(lane) { + return lane; } +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; -var emptyContextObject = {}; + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update + // could unblock them. Clear the suspended lanes so that we can try rendering + // them again. + // + // TODO: We really only need to unsuspend only lanes that are in the + // `subtreeLanes` of the updated fiber, or the update lanes of the return + // path. This would exclude suspended updates in an unrelated sibling tree, + // since there's no way for this update to unblock it. + // + // We don't do this if the incoming update is idle, because we never process + // idle updates until after all the regular updates have finished; there's no + // way it could unblock a transition. -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + if (updateLane !== IdleLane) { + root.suspendedLanes = NoLanes; + root.pingedLanes = NoLanes; + } -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. -var previousContext = emptyContextObject; + eventTimes[index] = eventTime; +} +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; - } + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - return contextStackCursor.current; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } - -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; - } +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; } +function markRootExpired(root, expiredLanes) { + root.expiredLanes |= expiredLanes & root.pendingLanes; +} +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLane) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; - - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. - - var instance = workInProgress.stateNode; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - var context = {}; + var lanes = noLongerPendingLanes; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + // In addition to entangling each of the given lanes with each other, we also + // have to consider _transitive_ entanglements. For each lane that is already + // entangled with *any* of the given lanes, that lane is now transitively + // entangled with *all* the given lanes. + // + // Translated: If C is entangled with A, then entangling A with B also + // entangles C with B. + // + // If this is hard to grasp, it might help to intentionally break this + // function and look at the tests that fail in ReactTransition-test.js. Try + // commenting out one of the conditions below. + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + var entanglements = root.entanglements; + var lanes = rootEntangledLanes; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + while (lanes) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); + if ( + // Is this one of the newly entangled lanes? + (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? + (entanglements[index] & entangledLanes) + ) { + entanglements[index] |= entangledLanes; } - return context; + lanes &= ~lane; } } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; - } -} +var log = Math.log; +var LN2 = Math.LN2; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } + + return (31 - ((log(lanes) / LN2) | 0)) | 0; } -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now$1 = Scheduler.unstable_now; + +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); } } +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -function popTopLevelContextObject(fiber) { +// can re-export everything from this module. + +function shim() { { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + 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; -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; +var UPDATE_SIGNAL = {}; - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); - } -} +{ + Object.freeze(UPDATE_SIGNAL); +} // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. +var nextReactTag = 3; - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; +function allocateTag() { + var tag = nextReactTag; - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; + if (tag % 10 === 1) { + tag += 2; + } - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } + nextReactTag = tag + 2; + return tag; +} - return parentContext; - } +function recursivelyUncacheFiberNode(node) { + if (typeof node === "number") { + // Leaf node (eg text) + uncacheFiberNode(node); + } else { + uncacheFiberNode(node._nativeTag); - var childContext = instance.getChildContext(); + node._children.forEach(recursivelyUncacheFiberNode); + } +} +function appendInitialChild(parentInstance, child) { + parentInstance._children.push(child); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = allocateTag(); + var viewConfig = getViewConfigForType(type); - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] ); } } + } - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + var updatePayload = create(props, viewConfig.validAttributes); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload // props + ); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); + precacheFiberNode(internalInstanceHandle, tag); + updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined + // in the same file but if it's external it can't see the types. - return Object.assign({}, parentContext, childContext); - } + return component; } +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); + } -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. + var tag = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + } // props + ); + precacheFiberNode(internalInstanceHandle, tag); + return tag; +} +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + // Don't send a no-op message over the bridge. + if (parentInstance._children.length === 0) { + return false; + } // Map from child objects to native tags. + // Either way we need to pass a copy of the Array to prevent it from being frozen. - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + var nativeTags = parentInstance._children.map(function(child) { + return typeof child === "number" + ? child // Leaf node (eg text) + : child._nativeTag; + }); - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; - } + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, // containerTag + nativeTags // reactTags + ); + return false; } +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; - - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - } - - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. - - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } +function getPublicInstance(instance) { + return instance; +} +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + return UPDATE_SIGNAL; +} +function resetAfterCommit(containerInfo) { + // Noop +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} +function appendChild(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + var children = parentInstance._children; + var index = children.indexOf(child); -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var node = fiber; - - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; - - case ClassComponent: { - var Component = node.type; - - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } - - break; - } - } - - node = node.return; - } while (node !== null); - - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + if (index >= 0) { + children.splice(index, 1); + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [index], // moveFromIndices + [children.length - 1], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [children.length - 1], // addAtIndices + [] // removeAtIndices + ); } } +function appendChildToContainer(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance, // containerTag + [childTag] // reactTags + ); +} +function commitTextUpdate(textInstance, oldText, newText) { + ReactNativePrivateInterface.UIManager.updateView( + textInstance, // reactTag + "RCTRawText", // viewName + { + text: newText + } // props + ); +} +function commitUpdate( + instance, + updatePayloadTODO, + type, + oldProps, + newProps, + internalInstanceHandle +) { + var viewConfig = instance.viewConfig; + updateFiberProps(instance._nativeTag, newProps); + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; - -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, // reactTag + viewConfig.uiViewClassName, // viewName + updatePayload // props + ); } +} +function insertBefore(parentInstance, child, beforeChild) { + var children = parentInstance._children; + var index = children.indexOf(child); // Move existing child or add new child? - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + if (index >= 0) { + children.splice(index, 1); + var beforeChildIndex = children.indexOf(beforeChild); + children.splice(beforeChildIndex, 0, child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [index], // moveFromIndices + [beforeChildIndex], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + var _beforeChildIndex = children.indexOf(beforeChild); - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; + children.splice(_beforeChildIndex, 0, child); + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [_beforeChildIndex], // addAtIndices + [] // removeAtIndices + ); } - - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. - - return true; +} +function insertInContainerBefore(parentInstance, child, beforeChild) { + // TODO (bvaughn): Remove this check when... + // We create a wrapper object for the container in ReactNative render() + // Or we refactor to remove wrapper objects entirely. + // For more info on pros/cons see PR #8560 description. + if (!(typeof parentInstance !== "number")) { + throw Error("Container does not support insertBefore operation"); } +} +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + var index = children.indexOf(child); + children.splice(index, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [index] // removeAtIndices + ); +} +function removeChildFromContainer(parentInstance, child) { + recursivelyUncacheFiberNode(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [0] // removeAtIndices + ); +} +function resetTextContent(instance) { + // Noop +} +function hideInstance(instance) { + var viewConfig = instance.viewConfig; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function hideTextInstance(textInstance) { + throw new Error("Not yet implemented."); +} +function unhideInstance(instance, props) { + var viewConfig = instance.viewConfig; + var updatePayload = diff( + Object.assign({}, props, { + style: [ + props.style, + { + display: "none" + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function clearContainer(container) { + // TODO Implement this for React Native + // UIManager does not expose a "remove all" type method. +} +function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists +function disabledLog() {} - return true; -} -function onScheduleRoot(root, children) { +disabledLog.__reactDisabledLog = true; +function disableLogs() { { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - error("React instrumentation encountered an error: %s", err); - } - } + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } + + disabledDepth++; } } -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; +function reenableLogs() { + { + disabledDepth--; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - error("React instrumentation encountered an error: %s", err); - } - } + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); } } } -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - error("React instrumentation encountered an error: %s", err); - } - } +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; + + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } + + return describeComponentFrame(name, source, ownerName); } } - -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now = Scheduler.unstable_now; +var componentFrameCache; { - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); } -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLanes = - /* */ - 24; -var InputContinuousHydrationLane = - /* */ - 32; -var InputContinuousLanes = - /* */ - 192; -var DefaultHydrationLane = - /* */ - 256; -var DefaultLanes = - /* */ - 3584; -var TransitionHydrationLane = - /* */ - 4096; -var TransitionLanes = - /* */ - 4186112; -var RetryLanes = - /* */ - 62914560; -var SomeRetryLane = - /* */ - 33554432; -var SelectiveHydrationLane = - /* */ - 67108864; -var NonIdleLanes = - /* */ - 134217727; -var IdleHydrationLane = - /* */ - 134217728; -var IdleLanes = - /* */ - 805306368; -var OffscreenLane = - /* */ - 1073741824; -var NoTimestamp = -1; -// Used by getHighestPriorityLanes and getNextLanes: + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". -var return_highestLanePriority = DefaultLanePriority; + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); -function getHighestPriorityLanes(lanes) { - if ((SyncLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncLanePriority; - return SyncLane; - } + if (match) { + var pathBeforeSlash = match[1]; - if ((SyncBatchedLane & lanes) !== NoLanes) { - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - } + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } + } + } - if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } - var inputDiscreteLanes = InputDiscreteLanes & lanes; + return "\n in " + (name || "Unknown") + sourceInfo; +} - if (inputDiscreteLanes !== NoLanes) { - return_highestLanePriority = InputDiscreteLanePriority; - return inputDiscreteLanes; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - if ((lanes & InputContinuousHydrationLane) !== NoLanes) { - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - } + var name = fn.displayName || fn.name || null; + var ownerName = null; - var inputContinuousLanes = InputContinuousLanes & lanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (inputContinuousLanes !== NoLanes) { - return_highestLanePriority = InputContinuousLanePriority; - return inputContinuousLanes; + return describeComponentFrame(name, source, ownerName); } +} - if ((lanes & DefaultHydrationLane) !== NoLanes) { - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; } - var defaultLanes = DefaultLanes & lanes; - - if (defaultLanes !== NoLanes) { - return_highestLanePriority = DefaultLanePriority; - return defaultLanes; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); + } } - if ((lanes & TransitionHydrationLane) !== NoLanes) { - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); } - var transitionLanes = TransitionLanes & lanes; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - if (transitionLanes !== NoLanes) { - return_highestLanePriority = TransitionPriority; - return transitionLanes; + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } - var retryLanes = RetryLanes & lanes; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); - if (retryLanes !== NoLanes) { - return_highestLanePriority = RetryLanePriority; - return retryLanes; - } + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - if (lanes & SelectiveHydrationLane) { - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; - } + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - if ((lanes & IdleHydrationLane) !== NoLanes) { - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } } - var idleLanes = IdleLanes & lanes; + return ""; +} - if (idleLanes !== NoLanes) { - return_highestLanePriority = IdleLanePriority; - return idleLanes; - } +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - if ((OffscreenLane & lanes) !== NoLanes) { - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } } +} +function checkPropTypes(typeSpecs, values, location, componentName, element) { { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); - return_highestLanePriority = DefaultLanePriority; - return lanes; -} + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - case UserBlockingPriority: - return InputContinuousLanePriority; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - case IdlePriority: - return IdleLanePriority; + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - default: - return NoLanePriority; + setCurrentlyValidatingElement(null); + } + + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + + error("Failed %s type: %s", location, error$1.message); + + setCurrentlyValidatingElement(null); + } + } + } } } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; +var valueStack = []; +var fiberStack; - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; +{ + fiberStack = []; +} - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; +var index = -1; - case NoLanePriority: - return NoPriority; +function createCursor(defaultValue) { + return { + current: defaultValue + }; +} - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); } - } -} -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; + return; } - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } + } - if (expiredLanes !== NoLanes) { - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + cursor.current = valueStack[index]; + valueStack[index] = null; - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + { + fiberStack[index] = null; + } - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; + index--; +} - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } + { + fiberStack[index] = fiber; } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If there are higher priority lanes, we'll include them even if they - // are suspended. + cursor.current = value; +} - nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. +var warnedAboutMissingGetChildContext; - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; +{ + warnedAboutMissingGetChildContext = {}; +} - if (nextLanePriority <= wipLanePriority) { - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; - } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. +var emptyContextObject = {}; - var entangledLanes = root.entangledLanes; +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. + +var previousContext = emptyContextObject; + +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; } + + return contextStackCursor.current; } +} - return nextLanes; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + } } -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. + + var instance = workInProgress.stateNode; + + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; } - lanes &= ~lane; - } + var context = {}; - return mostRecentEventTime; -} + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; } } -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. - - var lanes = pendingLanes; - - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; - - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); - } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; - } - - lanes &= ~lane; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; +} - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; } +} - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } - - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; } -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case NoLanePriority: - break; - case SyncLanePriority: - return SyncLane; +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } +} - case SyncBatchedLanePriority: - return SyncBatchedLane; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } - case InputDiscreteLanePriority: { - var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); + } +} - if (_lane === NoLane) { - // Shift to the next priority level - return findUpdateLane(InputContinuousLanePriority, wipLanes); - } +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. - return _lane; - } + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; - case InputContinuousLanePriority: { - var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - if (_lane2 === NoLane) { - // Shift to the next priority level - return findUpdateLane(DefaultLanePriority, wipLanes); + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } } - return _lane2; + return parentContext; } - case DefaultLanePriority: { - var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); - - if (_lane3 === NoLane) { - // If all the default lanes are already being worked on, look for a - // lane in the transition range. - _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + var childContext = instance.getChildContext(); - if (_lane3 === NoLane) { - // All the transition lanes are taken, too. This should be very - // rare, but as a last resort, pick a default lane. This will have - // the effect of interrupting the current work-in-progress render. - _lane3 = pickArbitraryLane(DefaultLanes); - } + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); } - - return _lane3; } - case TransitionPriority: // Should be handled by findTransitionLane instead + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); + } - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; + return Object.assign({}, parentContext, childContext); + } +} - case IdleLanePriority: - var lane = pickArbitraryLane(IdleLanes & ~wipLanes); +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. - if (lane === NoLane) { - lane = pickArbitraryLane(IdleLanes); - } + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - return lane; + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; } +} +function invalidateContextProvider(workInProgress, type, didChange) { { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. + var instance = workInProgress.stateNode; + + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } -function findTransitionLane(wipLanes, pendingLanes) { - // First look for lanes that are completely unclaimed, i.e. have no - // pending work. - var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. - if (lane === NoLane) { - // If all lanes have pending work, look for a lane that isn't currently - // being worked on. - lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - if (lane === NoLane) { - // If everything is being worked on, pick any lane. This has the - // effect of interrupting the current work-in-progress. - lane = pickArbitraryLane(TransitionLanes); + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } } +} - return lane; -} // To ensure consistency across multiple updates in the same event, this should -// be pure function, so that it always returns the same lane for given inputs. +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } -function findRetryLane(wipLanes) { - // This is a fork of `findUpdateLane` designed specifically for Suspense - // "retries" — a special update that attempts to flip a Suspense boundary - // from its placeholder state to its primary/resolved state. - var lane = pickArbitraryLane(RetryLanes & ~wipLanes); + var node = fiber; - if (lane === NoLane) { - lane = pickArbitraryLane(RetryLanes); - } + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; - return lane; -} + case ClassComponent: { + var Component = node.type; -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } -function getLowestPriorityLane(lanes) { - // This finds the most significant non-zero bit. - var index = 31 - clz32(lanes); - return index < 0 ? NoLanes : 1 << index; -} + break; + } + } -function getEqualOrHigherPriorityLanes(lanes) { - return (getLowestPriorityLane(lanes) << 1) - 1; -} + node = node.return; + } while (node !== null); -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; + } -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). - -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; } - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But - // it's not practical to try every single possible combination. We need a - // heuristic to decide which lanes to attempt to render, and in which batches. - // For now, we use the same heuristic as in the old ExpirationTimes model: - // retry any lane at equal or lower priority, but don't try updates at higher - // priority without also including the lower priority updates. This works well - // when considering updates across different priority levels, but isn't - // sufficient for updates within the same priority, since we want to treat - // those updates as parallel. - // Unsuspend any update at equal or lower priority. - - var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 - - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. - - eventTimes[index] = eventTime; -} -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + return true; } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLanes) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - var lanes = noLongerPendingLanes; + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } + return true; } -function markRootEntangled(root, entangledLanes) { - root.entangledLanes |= entangledLanes; - var entanglements = root.entanglements; - var lanes = entangledLanes; +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] |= entangledLanes; - lanes &= ~lane; + error("React instrumentation encountered an error: %s", err); + } + } + } } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; -var log = Math.log; -var LN2 = Math.LN2; + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; + error("React instrumentation encountered an error: %s", err); + } + } + } } - - return (31 - ((log(lanes) / LN2) | 0)) | 0; } +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; - -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); + error("React instrumentation encountered an error: %s", err); + } + } + } } } -var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. - -var ImmediatePriority$1 = 99; -var UserBlockingPriority$1 = 98; -var NormalPriority$1 = 97; -var LowPriority$1 = 96; -var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. -var NoPriority$1 = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. -var now = - initialTimeMs$1 < 10000 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority$1; +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority$1; +// TODO: this is special because it gets imported during build. +// +// TODO: 17.0.2 has not been released to NPM; +// It exists as a placeholder so that DevTools can support work tag changes between releases. +// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js +var ReactVersion = "17.0.2"; - case Scheduler_NormalPriority: - return NormalPriority$1; +var NoMode = + /* */ + 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead - case Scheduler_LowPriority: - return LowPriority$1; +var BlockingMode = + /* */ + 1; +var ConcurrentMode = + /* */ + 2; +var ProfileMode = + /* */ + 4; +var DebugTracingMode = + /* */ + 8; +var StrictLegacyMode = + /* */ + 16; - case Scheduler_IdlePriority: - return IdlePriority$1; +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var NoTransition = 0; +function requestCurrentTransition() { + return ReactCurrentBatchConfig.transition; +} - default: { - throw Error("Unknown priority level."); - } - } -} - -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority$1: - return Scheduler_ImmediatePriority; - - case UserBlockingPriority$1: - return Scheduler_UserBlockingPriority; - - case NormalPriority$1: - return Scheduler_NormalPriority; - - case LowPriority$1: - return Scheduler_LowPriority; - - case IdlePriority$1: - return Scheduler_IdlePriority; - - default: { - throw Error("Unknown priority level."); - } - } -} - -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. - - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); - } - - return fakeCallbackNode; -} -function cancelCallback(callbackNode) { - if (callbackNode !== fakeCallbackNode) { - Scheduler_cancelCallback(callbackNode); - } -} -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - - flushSyncCallbackQueueImpl(); -} - -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; - - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority$1, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; - - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick - - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ); - throw error; - } finally { - isFlushingSyncQueue = false; - } - } - } -} - -// TODO: this is special because it gets imported during build. -var ReactVersion = "17.0.1-454c2211c"; - -var NoMode = 0; -var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root -// tag instead - -var BlockingMode = 2; -var ConcurrentMode = 4; -var ProfileMode = 8; -var DebugTracingMode = 16; - -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -var NoTransition = 0; -function requestCurrentTransition() { - return ReactCurrentBatchConfig.transition; -} - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - return ( - (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare - ); +/** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ +function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare + ); } var objectIs = typeof Object.is === "function" ? Object.is : is; @@ -6205,7 +6279,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictMode) { + if (node.mode & StrictLegacyMode) { maybeStrictRoot = node; } @@ -6236,7 +6310,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedup strategy: Warn once per component. + // Dedupe strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -6249,7 +6323,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -6263,7 +6337,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -6277,7 +6351,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictMode && + fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6595,9 +6669,7 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, nextValue) { - var context = providerFiber.type._context; - +function pushProvider(providerFiber, context, nextValue) { { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; @@ -6618,10 +6690,9 @@ function pushProvider(providerFiber, nextValue) { } } } -function popProvider(providerFiber) { +function popProvider(context, providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); - var context = providerFiber.type._context; { context._currentValue = currentValue; @@ -6708,16 +6779,31 @@ function propagateContextChange( // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var update = createUpdate( - NoTimestamp, - pickArbitraryLane(renderLanes) - ); + var lane = pickArbitraryLane(renderLanes); + var update = createUpdate(NoTimestamp, lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. + // Inlined `enqueueUpdate` to remove interleaved update check + + var updateQueue = fiber.updateQueue; + + if (updateQueue === null); + else { + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - enqueueUpdate(fiber, update); + sharedQueue.pending = update; + } } fiber.lanes = mergeLanes(fiber.lanes, renderLanes); @@ -6852,6 +6938,48 @@ function readContext(context, observedBits) { return context._currentValue; } +// An array of all update queues that received updates during the current +// render. When this render exits, either because it finishes or because it is +// interrupted, the interleaved updates will be transfered onto the main part +// of the queue. +var interleavedQueues = null; +function pushInterleavedQueue(queue) { + if (interleavedQueues === null) { + interleavedQueues = [queue]; + } else { + interleavedQueues.push(queue); + } +} +function enqueueInterleavedUpdates() { + // Transfer the interleaved updates onto the main queue. Each queue has a + // `pending` field and an `interleaved` field. When they are not null, they + // point to the last node in a circular linked list. We need to append the + // interleaved list to the end of the pending list by joining them into a + // single, circular list. + if (interleavedQueues !== null) { + for (var i = 0; i < interleavedQueues.length; i++) { + var queue = interleavedQueues[i]; + var lastInterleavedUpdate = queue.interleaved; + + if (lastInterleavedUpdate !== null) { + queue.interleaved = null; + var firstInterleavedUpdate = lastInterleavedUpdate.next; + var lastPendingUpdate = queue.pending; + + if (lastPendingUpdate !== null) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = firstInterleavedUpdate; + lastInterleavedUpdate.next = firstPendingUpdate; + } + + queue.pending = lastInterleavedUpdate; + } + } + + interleavedQueues = null; + } +} + var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -6874,7 +7002,9 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null + pending: null, + interleaved: null, + lanes: NoLanes }, effects: null }; @@ -6907,7 +7037,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update) { +function enqueueUpdate(fiber, update, lane) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -6916,17 +7046,35 @@ function enqueueUpdate(fiber, update) { } var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; + if (isInterleavedUpdate(fiber)) { + var interleaved = sharedQueue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(sharedQueue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + sharedQueue.interleaved = update; } else { - update.next = pending.next; - pending.next = update; - } + var pending = sharedQueue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } - sharedQueue.pending = update; + sharedQueue.pending = update; + } { if ( @@ -6944,6 +7092,33 @@ function enqueueUpdate(fiber, update) { } } } +function entangleTransitions(root, fiber, lane) { + var updateQueue = fiber.updateQueue; + + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } + + var sharedQueue = updateQueue.shared; + + if (isTransitionLane(lane)) { + var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must + // have finished. We can remove them from the shared queue, which represents + // a superset of the actually pending lanes. In some cases we may entangle + // more than we need to, but that's OK. In fact it's worse if we *don't* + // entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } +} function enqueueCapturedUpdate(workInProgress, capturedUpdate) { // Captured updates are updates that are thrown by a child during the render // phase. They should be discarded if the render is aborted. Therefore, @@ -7045,7 +7220,7 @@ function getStateFromUpdate( var nextState = payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7083,7 +7258,7 @@ function getStateFromUpdate( partialState = _payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7273,7 +7448,24 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.shared.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + newLanes = mergeLanes(newLanes, interleaved.lane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (firstBaseUpdate === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.shared.lanes = NoLanes; + } // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7414,7 +7606,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7463,7 +7655,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7482,7 +7678,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7500,7 +7700,11 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, fiber, lane); + } } }; @@ -7517,7 +7721,7 @@ function checkShouldComponentUpdate( if (typeof instance.shouldComponentUpdate === "function") { { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -7853,7 +8057,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { @@ -8066,7 +8270,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -8110,7 +8314,9 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } @@ -8172,7 +8378,9 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } return false; @@ -8218,13 +8426,17 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - workInProgress.flags |= Update; + { + workInProgress.flags |= Update; + } } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8474,7 +8686,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8576,12 +8788,14 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { + var childString = Object.prototype.toString.call(newChild); + { throw Error( "Objects are not valid as a React child (found: " + - (Object.prototype.toString.call(newChild) === "[object Object]" + (childString === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : childString) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8604,7 +8818,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} // This wrapper function exists because I expect to clone the code in each path +} // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8614,23 +8828,16 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } // Deletions are added in reversed order so we add it to the front. - // At this point, the return fiber's effect list is empty except for - // deletions, so we can just append the deletion to the list. The remaining - // effects aren't added until the complete phase. Once we implement - // resuming, this may not be true. + } - var last = returnFiber.lastEffect; + var deletions = returnFiber.deletions; - if (last !== null) { - last.nextEffect = childToDelete; - returnFiber.lastEffect = childToDelete; + if (deletions === null) { + returnFiber.deletions = [childToDelete]; + returnFiber.flags |= ChildDeletion; } else { - returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; + deletions.push(childToDelete); } - - childToDelete.nextEffect = null; - childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8694,7 +8901,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8702,7 +8909,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags = Placement; + newFiber.flags |= Placement; return lastPlacedIndex; } } @@ -8711,7 +8918,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags = Placement; + newFiber.flags |= Placement; } return newFiber; @@ -8732,10 +8939,26 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { + var elementType = element.type; + + if (elementType === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + } + if (current !== null) { if ( - current.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) + current.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements ) { // Move based on index var existing = useFiber(current, element.props); @@ -8874,16 +9097,6 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ); - } - return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8941,16 +9154,6 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; - if (newChild.type === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - _matchedFiber, - newChild.props.children, - lanes, - newChild.key - ); - } - return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9444,45 +9647,43 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - switch (child.tag) { - case Fragment: { - if (element.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + var elementType = element.type; - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; - } + if (elementType === REACT_FRAGMENT_TYPE) { + if (child.tag === Fragment) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - return existing; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; } - break; + return existing; } + } else { + if ( + child.elementType === elementType || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. + // We need to do this after the Hot Reloading check above, + // because hot reloading has different semantics than prod because + // it doesn't resuspend. So we can't let the call below suspend. + enableLazyElements + ) { + deleteRemainingChildren(returnFiber, child.sibling); - default: { - if ( - child.elementType === element.type || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) - ) { - deleteRemainingChildren(returnFiber, child.sibling); - - var _existing = useFiber(child, element.props); - - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + var _existing = useFiber(child, element.props); - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; - } + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - return _existing; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; } - break; + return _existing; } } // Didn't match. @@ -9913,21 +10114,6 @@ function findFirstSuspended(row) { return null; } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. - -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. - -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; - var isHydrating = false; function enterHydrationState(fiber) { @@ -10023,6 +10209,12 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. +function getSuspendedCachePool() { + { + return null; + } // We check the cache on the stack first, since that's the one any new Caches +} + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -10308,7 +10500,20 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; + hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last + // render. If this fires, it suggests that we incorrectly reset the static + // flags in some other part of the codebase. This has happened before, for + // example, in the SuspenseList implementation. + + if ( + current !== null && + (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) + ) { + error( + "Internal React error: Expected static flag was missing. Please " + + "notify the React team." + ); + } } didScheduleRenderPhaseUpdate = false; @@ -10322,8 +10527,13 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; - workInProgress.flags &= ~(Passive | Update); + workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the + // complete phase (bubbleProperties). + + { + workInProgress.flags &= ~(Passive | Update); + } + current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10474,6 +10684,8 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10611,6 +10823,28 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; + } // Interleaved updates are stored on a separate queue. We aren't going to + // process them during this render, but we do need to track which lanes + // are remaining. + + var lastInterleaved = queue.interleaved; + + if (lastInterleaved !== null) { + var interleaved = lastInterleaved; + + do { + var interleavedLane = interleaved.lane; + currentlyRenderingFiber$1.lanes = mergeLanes( + currentlyRenderingFiber$1.lanes, + interleavedLane + ); + markSkippedUpdateLanes(interleavedLane); + interleaved = interleaved.next; + } while (interleaved !== lastInterleaved); + } else if (baseQueue === null) { + // `queue.lanes` is used for entangling transitions. We can set it back to + // zero once the queue is empty. + queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10738,11 +10972,48 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); + markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During + // the synchronous retry, it will block interleaved mutations, so we should + // get a consistent read. Therefore, the following error should never be + // visible to the user. + // + // If it were to become visible to the user, it suggests one of two things: + // a bug in React, or (more likely), a mutation during the render phase that + // caused the second re-render attempt to be different from the first. + // + // We know it's the second case if the logs are currently disabled. So in + // dev, we can present a more accurate error message. + + { + // eslint-disable-next-line react-internal/no-production-logging + if (console.log.__reactDisabledLog) { + // If the logs are disabled, this is the dev-only double render. This is + // only reachable if there was a mutation during render. Show a helpful + // error message. + // + // Something interesting to note: because we only double render in + // development, this error will never happen during production. This is + // actually true of all errors that occur during a double render, + // because if the first render had thrown, we would have exited the + // begin phase without double rendering. We should consider suppressing + // any error from a double render (with a warning) to more closely match + // the production behavior. + var componentName = getComponentName(currentlyRenderingFiber$1.type); + + { + throw Error( + "A mutable source was mutated while the " + + componentName + + " component was rendering. This is not supported. Move any mutations into event handlers or effects." + ); + } + } + } // We expect this error not to be thrown during the synchronous retry, + // because we blocked interleaved mutations. { throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } } @@ -10878,6 +11149,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10925,6 +11198,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, + interleaved: null, + lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -11018,7 +11293,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - pushEffect(hookFlags, create, destroy, nextDeps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -11041,7 +11316,9 @@ function mountEffect(create, deps) { } } - return mountEffectImpl(Update | Passive, Passive$1, create, deps); + { + return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); + } } function updateEffect(create, deps) { @@ -11052,11 +11329,13 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Update | Passive, Passive$1, create, deps); + return updateEffectImpl(Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - return mountEffectImpl(Update, Layout, create, deps); + { + return mountEffectImpl(Update, Layout, create, deps); + } } function updateLayoutEffect(create, deps) { @@ -11108,12 +11387,15 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); + + { + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); + } } function updateImperativeHandle(ref, create, deps) { @@ -11268,15 +11550,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority$1 - ? UserBlockingPriority$1 + priorityLevel < UserBlockingPriority + ? UserBlockingPriority : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, + priorityLevel > NormalPriority ? NormalPriority : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11388,19 +11670,7 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; // Append the update to the end of the list. - - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; + }; var alternate = fiber.alternate; if ( @@ -11411,7 +11681,47 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; } else { + if (isInterleavedUpdate(fiber)) { + var interleaved = queue.interleaved; + + if (interleaved === null) { + // This is the first update. Create a circular list. + update.next = update; // At the end of the current render, this queue's interleaved updates will + // be transfered to the pending queue. + + pushInterleavedQueue(queue); + } else { + update.next = interleaved.next; + interleaved.next = update; + } + + queue.interleaved = update; + } else { + var _pending = queue.pending; + + if (_pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = _pending.next; + _pending.next = update; + } + + queue.pending = update; + } + if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11464,7 +11774,24 @@ function dispatchAction(fiber, queue, action) { } } - scheduleUpdateOnFiber(fiber, lane, eventTime); + var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + + if (isTransitionLane(lane) && root !== null) { + var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they + // must have finished. We can remove them from the shared queue, which + // represents a superset of the actually pending lanes. In some cases we + // may entangle more than we need to, but that's OK. In fact it's worse if + // we *don't* entangle when we should. + + queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. + + var newQueueLanes = mergeLanes(queueLanes, lane); + queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if + // the lane finished since the last time we entangled it. So we need to + // entangle it again, just to be sure. + + markRootEntangled(root, newQueueLanes); + } } } @@ -11486,6 +11813,7 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; + var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11615,6 +11943,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11712,6 +12041,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11809,6 +12139,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11906,6 +12237,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12018,6 +12350,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12130,6 +12463,7 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12172,218 +12506,621 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; var prevDispatcher = ReactCurrentDispatcher$1.current; ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; +} + +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; + +function getCommitTime() { + return commitTime; +} + +function recordCommitTime() { + commitTime = now$1(); +} + +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); + + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} + +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} + +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; + + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; + } + + profilerStartTime = -1; + } +} + +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; + + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} + +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 +) { + // 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; + + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) + ); + } + } + } + + 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 (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes + ); + } finally { + reenableLogs(); + } + } + + setIsRendering(false); + } + + 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 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; + + { + 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. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + 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", + getComponentName(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 _type = Component.type; + 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", + getComponentName(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one child - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; + 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 - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; -} + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } + } // React DevTools reads this flag. -function getCommitTime() { - return commitTime; + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; } -function recordCommitTime() { - commitTime = now$1(); -} +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; -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); + 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 (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); + try { + 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", + getComponentName(outerMemoType) + ); + } + } + } } -} -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; + if (current !== null) { + var prevProps = current.memoizedProps; + + 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 (!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 accumlated 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; + } + } + } + + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; +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 (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; + 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. + // TODO: Figure out what we should do in Blocking mode. + 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. + + { + markSpawnedWork(OffscreenLane); + } + + 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); + 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; + + if (prevState !== null) { + // We're going from hidden -> visible. + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); + + 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; } - profilerStartTime = -1; + pushRenderLanes(workInProgress, _subtreeRenderLanes); } -} -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; + 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. - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} +var updateLegacyHiddenComponent = updateOffscreenComponent; -var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; -var didReceiveUpdate = false; -var didWarnAboutBadClass; -var didWarnAboutModulePatternComponent; -var didWarnAboutContextTypeOnFunctionComponent; -var didWarnAboutGetDerivedStateOnFunctionComponent; -var didWarnAboutFunctionRefs; -var didWarnAboutReassigningProps; -var didWarnAboutRevealOrder; -var didWarnAboutTailOptions; +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} -{ - didWarnAboutBadClass = {}; - didWarnAboutModulePatternComponent = {}; - didWarnAboutContextTypeOnFunctionComponent = {}; - didWarnAboutGetDerivedStateOnFunctionComponent = {}; - didWarnAboutFunctionRefs = {}; - didWarnAboutReassigningProps = false; - didWarnAboutRevealOrder = {}; - didWarnAboutTailOptions = {}; +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; } -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 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 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. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - workInProgress.child = reconcileChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function updateForwardRef( +function updateFunctionComponent( 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 @@ -12401,8 +13138,12 @@ function updateForwardRef( } } - var render = Component.render; - var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -12413,22 +13154,22 @@ function updateForwardRef( nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); - if (workInProgress.mode & StrictMode) { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { nextChildren = renderWithHooks( current, workInProgress, - render, + Component, nextProps, - ref, + context, renderLanes ); } finally { @@ -12449,424 +13190,442 @@ function updateForwardRef( return workInProgress.child; } -function updateMemoComponent( +function updateClassComponent( 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; - - { - 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. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - renderLanes - ); - } - - { - var innerPropTypes = type.propTypes; + { + 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) { - // 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", - getComponentName(type) + getComponentName(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. - var child = createFiberFromTypeAndProps( - Component.type, - null, - nextProps, - workInProgress, - workInProgress.mode, - renderLanes - ); - child.ref = workInProgress.ref; - child.return = workInProgress; - workInProgress.child = child; - return child; + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; } - { - var _type = Component.type; - var _innerPropTypes = _type.propTypes; + prepareToReadContext(workInProgress, renderLanes); + var instance = workInProgress.stateNode; + var shouldUpdate; - 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", - getComponentName(_type) - ); - } + 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 currentChild = current.child; // This is always exactly one child + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); - 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 + { + var inst = workInProgress.stateNode; - var compare = Component.compare; - compare = compare !== null ? compare : shallowEqual; + 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.", + getComponentName(workInProgress.type) || "a component" + ); + } - if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didWarnAboutReassigningProps = true; } - } // 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; + return nextUnitOfWork; } -function updateSimpleMemoComponent( +function finishClassComponent( current, workInProgress, Component, - nextProps, - updateLanes, + shouldUpdate, + hasContext, 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; + // Refs should update even if shouldComponentUpdate returns false + markRef(current, workInProgress); + var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags; - 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 (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); + } - try { - outerMemoType = init(payload); - } catch (x) { - outerMemoType = null; - } // Inner propTypes will be validated in the function component path. + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - var outerPropTypes = outerMemoType && outerMemoType.propTypes; + var instance = workInProgress.stateNode; // Rerender - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - nextProps, // Resolved (SimpleMemoComponent has no defaultProps) - "prop", - getComponentName(outerMemoType) - ); + 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; + + { + stopProfilerTimerIfRunning(); + } + } else { + { + setIsRendering(true); + nextChildren = instance.render(); + + if (workInProgress.mode & StrictLegacyMode) { + disableLogs(); + + try { + instance.render(); + } finally { + reenableLogs(); } } + + setIsRendering(false); } - } + } // React DevTools reads this flag. - if (current !== null) { - var prevProps = current.memoizedProps; + workInProgress.flags |= PerformedWork; - 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 (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. - 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 accumlated 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; - } - } + workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + + if (hasContext) { + invalidateContextProvider(workInProgress, Component, true); } - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); + return workInProgress.child; } -function updateOffscreenComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - var prevState = current !== null ? current.memoizedState : null; - - if ( - nextProps.mode === "hidden" || - nextProps.mode === "unstable-defer-without-hiding" - ) { - if ((workInProgress.mode & ConcurrentMode) === NoMode) { - // In legacy sync mode, don't defer the subtree. Render it now. - // TODO: Figure out what we should do in Blocking mode. - var nextState = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = nextState; - pushRenderLanes(workInProgress, renderLanes); - } else if (!includesSomeLane(renderLanes, OffscreenLane)) { - 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. +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - { - markSpawnedWork(OffscreenLane); - } + if (root.pendingContext) { + pushTopLevelContextObject( + workInProgress, + root.pendingContext, + root.pendingContext !== root.context + ); + } else if (root.context) { + // Should always be set + pushTopLevelContextObject(workInProgress, root.context, false); + } - workInProgress.lanes = workInProgress.childLanes = laneToLanes( - OffscreenLane - ); - var _nextState = { - baseLanes: nextBaseLanes - }; - workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway - // to avoid a push/pop misalignment. + pushHostContainer(workInProgress, root.containerInfo); +} - pushRenderLanes(workInProgress, nextBaseLanes); - return null; - } else { - // Rendering at offscreen, so we can clear the base lanes. - var _nextState2 = { - baseLanes: NoLanes - }; - workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } - } else { - var _subtreeRenderLanes; + 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 (prevState !== null) { - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state + 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". - 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 nextChildren = nextState.element; - pushRenderLanes(workInProgress, _subtreeRenderLanes); + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } - 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. + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; -var updateLegacyHiddenComponent = updateOffscreenComponent; + 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 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 updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); -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 type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; + 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; } - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; + markRef(current, workInProgress); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.ref; +function updateHostText(current, workInProgress) { + // immediately after. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + return null; } -function updateFunctionComponent( - current, +function mountLazyComponent( + _current, workInProgress, - Component, - nextProps, + elementType, + updateLanes, 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 (_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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } + workInProgress.flags |= Placement; } - var context; + 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. - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component + ); + } - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes - ); + child = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - if (workInProgress.mode & StrictMode) { - disableLogs(); + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } - try { - nextChildren = renderWithHooks( - current, - workInProgress, - Component, - nextProps, - context, - renderLanes + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } + + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - } finally { - reenableLogs(); } + + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; } - setIsRendering(false); + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } + } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } } - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } // React DevTools reads this flag. + var hint = ""; - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + { + 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 + ); + } } -function updateClassComponent( - current, +function mountIncompleteClassComponent( + _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 (_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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } // Push context providers early to prevent context stack mismatches. + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. + + 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. @@ -12880,2412 +13639,2644 @@ function updateClassComponent( } prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); +} - 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 +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 - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + workInProgress.flags |= Placement; + } - 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, + var props = workInProgress.pendingProps; + var context; + + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } + + prepareToReadContext(workInProgress, renderLanes); + var value; + + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; + + 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; + } + } + + if (workInProgress.mode & StrictLegacyMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } + + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, workInProgress, Component, - nextProps, + props, + context, renderLanes ); - } + setIsRendering(false); + } // React DevTools reads this flag. - var nextUnitOfWork = finishClassComponent( - current, - workInProgress, - Component, - shouldUpdate, - hasContext, - renderLanes - ); + workInProgress.flags |= PerformedWork; { - var inst = workInProgress.stateNode; + // 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 = getComponentName(Component) || "Unknown"; - if (shouldUpdate && inst.props !== nextProps) { - if (!didWarnAboutReassigningProps) { + if (!didWarnAboutModulePatternComponent[_componentName]) { error( - "It looks like %s is reassigning its own `this.props` while rendering. " + - "This is not supported and can lead to confusing bugs.", - getComponentName(workInProgress.type) || "a component" + "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 ); - } - didWarnAboutReassigningProps = true; + didWarnAboutModulePatternComponent[_componentName] = true; + } } } - return nextUnitOfWork; -} + 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 = getComponentName(Component) || "Unknown"; -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 (!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 + ); - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } + didWarnAboutModulePatternComponent[_componentName2] = true; + } + } // Proceed under the assumption that this is a class instance - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + workInProgress.tag = ClassComponent; // Throw out any hooks that were used. - var instance = workInProgress.stateNode; // Rerender + 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. - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; + var hasContext = false; - 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 (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); + } else { + hasContext = false; + } - { - stopProfilerTimerIfRunning(); + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; + + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); } + + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); } else { - { - setIsRendering(true); - nextChildren = instance.render(); + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - if (workInProgress.mode & StrictMode) { + { + if (workInProgress.mode & StrictLegacyMode) { disableLogs(); try { - instance.render(); + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); } 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. + reconcileChildren(null, workInProgress, value, renderLanes); - workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it. + { + validateFunctionComponentInDev(workInProgress, Component); + } - if (hasContext) { - invalidateContextProvider(workInProgress, Component, true); + return workInProgress.child; } - - return workInProgress.child; } -function pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - - if (root.pendingContext) { - pushTopLevelContextObject( - workInProgress, - root.pendingContext, - root.pendingContext !== root.context - ); - } else if (root.context) { - // Should always be set - pushTopLevelContextObject(workInProgress, root.context, 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" + ); + } + } - pushHostContainer(workInProgress, root.containerInfo); -} + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - 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 warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - var nextProps = workInProgress.pendingProps; - var prevState = workInProgress.memoizedState; - var prevChildren = prevState !== null ? prevState.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextProps, null, renderLanes); - var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property - // being called "element". + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - var nextChildren = nextState.element; + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info + ); + } + } - var root = workInProgress.stateNode; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); - 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; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } } - } 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); + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); - 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; + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } + } } - - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - return null; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes, + cachePool: getSuspendedCachePool() + }; } -function mountLazyComponent( - _current, +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, - 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 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; - workInProgress.flags |= Placement; + 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. + + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); +} + +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} + +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } + } + + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + + 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. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } } - 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. + 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. - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - child = updateFunctionComponent( - null, + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, + 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, - Component, - resolvedProps, + nextPrimaryChildren, + nextFallbackChildren, renderLanes ); - return child; - } - - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component - ); - } - child = updateForwardRef( - null, - workInProgress, - Component, - resolvedProps, + var _primaryChildFragment = workInProgress.child; + _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( renderLanes ); - return child; - } + 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 MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; + workInProgress.lanes = SomeRetryLane; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } + { + markSpawnedWork(SomeRetryLane); } - child = updateMemoComponent( - null, + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, + nextPrimaryChildren, renderLanes ); - return child; - } - } - - 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 - ); - } -} - -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 - - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. - - 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 hasContext; - - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); } else { - hasContext = false; - } - - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); -} - -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 - - workInProgress.flags |= Placement; - } - - var props = workInProgress.pendingProps; - var context; + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); - context = getMaskedContext(workInProgress, unmaskedContext); - } + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - prepareToReadContext(workInProgress, renderLanes); - var value; + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes + ); - { - if ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + 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 (!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 + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes ); - didWarnAboutBadClass[componentName] = true; + workInProgress.memoizedState = null; + return _primaryChildFragment4; } - } - - if (workInProgress.mode & StrictMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + } else { + // The current tree is not already showing a fallback. + if (showFallback) { + // Timed out. + var _nextFallbackChildren3 = nextProps.fallback; + var _nextPrimaryChildren4 = nextProps.children; - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - setIsRendering(false); - } // React DevTools reads this flag. + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, + workInProgress, + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes + ); - workInProgress.flags |= PerformedWork; + 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. - { - // 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 = getComponentName(Component) || "Unknown"; + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; - 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 _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + renderLanes ); - didWarnAboutModulePatternComponent[_componentName] = true; + workInProgress.memoizedState = null; + return _primaryChildFragment6; } } } +} - 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 = getComponentName(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 - - 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; +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; +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + if ((mode & BlockingMode) === 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 (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + 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; } - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; - - { - if (workInProgress.mode & StrictMode) { - disableLogs(); + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } - } - } + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - reconcileChildren(null, workInProgress, value, renderLanes); +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, { - validateFunctionComponentInDev(workInProgress, Component); + mode: "visible", + children: primaryChildren } + ); - return workInProgress.child; + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; } -} - -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 (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + var deletions = workInProgress.deletions; - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + if (deletions === null) { + workInProgress.deletions = [currentFallbackChildFragment]; + workInProgress.flags |= ChildDeletion; + } else { + deletions.push(currentFallbackChildFragment); + } + } - if (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; +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; - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } - } + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === 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 (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; + 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. - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); + 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.) - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } + primaryChildFragment.subtreeFlags = + currentPrimaryChildFragment.subtreeFlags & StaticMask; + } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; + var fallbackChildFragment; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 - ); + 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. - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; - } - } + fallbackChildFragment.flags |= Placement; } + + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes - }; -} + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) - }; -} // TODO: Probably should inline this back + scheduleWorkOnParentPath(fiber.return, renderLanes); +} -function shouldRemainOnFallback( - suspenseContext, - current, +function propagateSuspenseContextChange( workInProgress, + firstChild, 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. - - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); -} - -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, 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 updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; + 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 suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + if (node === workInProgress) { + return; + } - 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. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } + + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } +} - 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. +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 (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; + } - 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 - ); + row = row.sibling; + } - 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. + return lastContentRow; +} - workInProgress.lanes = SomeRetryLane; +function validateRevealOrder(revealOrder) { + { + if ( + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] + ) { + didWarnAboutRevealOrder[revealOrder] = true; - { - markSpawnedWork(SomeRetryLane); - } + 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 _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; + break; + } - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; + 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() + ); - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes - ); + 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; + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + + break; + } } else { - var _nextPrimaryChildren3 = nextProps.children; + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } +} - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes +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; - workInProgress.memoizedState = null; - return _primaryChildFragment4; + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); } - } 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 - ); +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - 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. + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); + + return false; + } + } - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; + return true; +} + +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; + var iteratorFn = getIteratorFn(children); - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - workInProgress.memoizedState = null; - return _primaryChildFragment6; + 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 + ); + } } } } } -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; -} - -function mountSuspenseFallbackChildren( +function initSuspenseListRenderState( workInProgress, - primaryChildren, - fallbackChildren, - renderLanes + isBackwards, + tail, + lastContentRow, + tailMode ) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; + var renderState = workInProgress.memoizedState; - if ((mode & BlockingMode) === 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 (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 (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; - } +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 + ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback ); + workInProgress.flags |= DidCapture; } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + 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 + ); + } + + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - primaryChildFragment.return = workInProgress; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + pushSuspenseContext(workInProgress, suspenseContext); -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); -} + if ((workInProgress.mode & BlockingMode) === 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 (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; + } + + 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. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } + + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode + ); + break; + } -function updateSuspensePrimaryChildren( - current, - workInProgress, - primaryChildren, - renderLanes -) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren - } - ); + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined + ); + break; + } - if ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } + } } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; + return workInProgress.child; +} - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - currentFallbackChildFragment.nextEffect = null; - currentFallbackChildFragment.flags = Deletion; - workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; + + 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); } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; + return workInProgress.child; } -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; - - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === 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; +var hasWarnedAboutUsingNoValuePropOnContextProvider = 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 effect during the first pass. - // However, since we're going to remain on the fallback, we no longer want - // to delete it. So we need to remove it from the list. Deletions are stored - // on the same list as effects. We want to keep the effects from the primary - // tree. So we copy the primary child fragment's effect list, which does not - // include the fallback deletion effect. +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; - var progressedLastEffect = primaryChildFragment.lastEffect; + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; - if (progressedLastEffect !== null) { - workInProgress.firstEffect = primaryChildFragment.firstEffect; - workInProgress.lastEffect = progressedLastEffect; - progressedLastEffect.nextEffect = null; - } else { - // TODO: Reset this somewhere else? Lol legacy mode is so weird. - workInProgress.firstEffect = workInProgress.lastEffect = null; + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); + } } - } else { - primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - primaryChildProps - ); - } - - 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 providerPropTypes = workInProgress.type.propTypes; - fallbackChildFragment.flags |= Placement; + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } } - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + pushProvider(workInProgress, context, newValue); -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + if (changedBits === 0) { + // 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, changedBits, renderLanes); + } } - scheduleWorkOnParentPath(fiber.return, renderLanes); + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -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; +var hasWarnedAboutUsingContextAsConsumer = false; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; +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 (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + { + 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 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; + } else { + context = context._context; } + } - if (node === workInProgress) { - return; + 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." + ); } + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; + + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - node = node.return; - } + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - node.sibling.return = node.return; - node = node.sibling; - } +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; } -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; +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; - } + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - row = row.sibling; + 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; + } else { + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; } - - return lastContentRow; } -function validateRevealOrder(revealOrder) { +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + var returnFiber = oldWorkInProgress.return; - 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() - ); + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - break; - } + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - 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() - ); + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - break; - } + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } - break; + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; + + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); } - } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - 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 deletions = returnFiber.deletions; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode - ); - } + if (deletions === null) { + returnFiber.deletions = [current]; + returnFiber.flags |= ChildDeletion; + } else { + deletions.push(current); } + + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + + return newWorkInProgress; } } -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - error( - "A nested %s was passed to row #%s in . Wrap it in " + - "an additional SuspenseList to configure its revealOrder: " + - " ... " + - "{%s} ... " + - "", - type, - index, - type + { + 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 + ) ); - - return false; } } - return true; -} + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; -function validateSuspenseListChildren(children, revealOrder) { - { if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false + oldProps !== newProps || + hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: + workInProgress.type !== current.type ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; + // 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; + + case ClassComponent: { + var Component = workInProgress.type; + + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); } + + break; } - } else { - var iteratorFn = getIteratorFn(children); - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + 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; + } + + break; - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + case SuspenseComponent: { + var state = workInProgress.memoizedState; - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + 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. - _i++; + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; + + 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 { + return null; + } } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); } - } 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 initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode, - lastEffectBeforeRendering -) { - var renderState = workInProgress.memoizedState; + break; + } - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering - }; - } 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; - renderState.lastEffect = lastEffectBeforeRendering; - } -} // 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. + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; -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 _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - if (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + 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. - 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 - ); - } + 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. - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var renderState = workInProgress.memoizedState; - pushSuspenseContext(workInProgress, suspenseContext); + 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; + } - if ((workInProgress.mode & BlockingMode) === 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; + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - 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; + 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; + } } - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode, - workInProgress.lastEffect - ); - break; + 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); + } } - 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. - - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + 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; + } + } + } 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. - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + workInProgress.lanes = NoLanes; - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode, - workInProgress.lastEffect - ); - break; - } + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined, - workInProgress.lastEffect - ); - break; - } + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; - } + 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 + ); } - } - return workInProgress.child; -} + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - 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); - } + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); + } - return workInProgress.child; -} + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); -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; + case HostText: + return updateHostText(); - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } - } + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - var providerPropTypes = workInProgress.type.propTypes; + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); + + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); } - } - pushProvider(workInProgress, newValue); + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + case Mode: + return updateMode(current, workInProgress, renderLanes); - if (changedBits === 0) { - // 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, changedBits, renderLanes); - } - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); -var hasWarnedAboutUsingContextAsConsumer = false; + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); -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. + case MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - { - 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; + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; + + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); + } } } - } else { - context = context._context; + + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - } - var newProps = workInProgress.pendingProps; - var render = newProps.children; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } - { - 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 IncompleteClassComponent: { + var _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; + + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); + + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes ); } - } - - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + case SuspenseListComponent: { + return updateSuspenseListComponent(current, workInProgress, renderLanes); + } - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + case ScopeComponent: { + break; + } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + case OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } } { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); } +} - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} - 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; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. +{ + // 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; - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + 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; + } - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (node === workInProgress) { + return; + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + node = node.return; } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + node.sibling.return = node.return; + node = node.sibling; + } + }; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } - } + updateHostContainer = function(current, workInProgress) { + // Noop + }; - prevSibling.sibling = newWorkInProgress; - } // Delete the old fiber and place the new one. - // Since the old fiber is disconnected, we have to schedule it manually. + 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; - var last = returnFiber.lastEffect; + 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 (last !== null) { - last.nextEffect = current; - returnFiber.lastEffect = current; - } else { - returnFiber.firstEffect = returnFiber.lastEffect = current; - } + 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`. - current.nextEffect = null; - current.flags = Deletion; - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - return newWorkInProgress; - } -} + 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. -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + if (updatePayload) { + markUpdate(workInProgress); + } + }; - { - 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 - ) - ); + 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); } - } + }; +} - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; +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 ( - 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. + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case HostComponent: - pushHostContext(workInProgress); - break; + 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; + } - case ClassComponent: { - var Component = workInProgress.type; + break; + } + + 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 (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - 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 HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; + break; + } + } +} - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - pushProvider(workInProgress, newValue); - break; - } +function bubbleProperties(completedWork) { + var didBailout = + completedWork.alternate !== null && + completedWork.alternate.child === completedWork.child; + var newChildLanes = NoLanes; + var subtreeFlags = NoFlags; - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + 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 (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, + 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. - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + actualDuration += child.actualDuration; + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } - break; + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; - case SuspenseComponent: { - var state = workInProgress.memoizedState; + 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 (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. + _child.return = completedWork; + _child = _child.sibling; + } + } - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + 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; + + 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. + + subtreeFlags |= _child2.subtreeFlags & StaticMask; + subtreeFlags |= _child2.flags & StaticMask; + _treeBaseDuration += _child2.treeBaseDuration; + _child2 = _child2.sibling; + } + + completedWork.treeBaseDuration = _treeBaseDuration; + } else { + var _child3 = completedWork.child; - 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. + 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 child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + 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 (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + _child3.return = completedWork; + _child3 = _child3.sibling; + } + } - break; - } + completedWork.subtreeFlags |= subtreeFlags; + } - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; - 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. + 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; - 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 ClassComponent: { + 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); + case HostRoot: { + var fiberRoot = workInProgress.stateNode; - 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; - } - } + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); - 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 (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; } - 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 (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 (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; + } } + + updateHostContainer(current, workInProgress); + bubbleProperties(workInProgress); + return null; } - } 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; + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + 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. + + bubbleProperties(workInProgress); + return null; + } - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + 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. - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + var _wasHydrated = popHydrationState(); - 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 (_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. - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + } - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); + case HostText: { + var newText = newProps; - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + 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. - case HostText: - return updateHostText(); + 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. + } - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + var _rootContainerInstance = getRootHostContainer(); - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + var _currentHostContext = getHostContext(); - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + var _wasHydrated2 = popHydrationState(); - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } - case Fragment: - return updateFragment(current, workInProgress, renderLanes); + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - case Mode: - return updateMode(current, workInProgress, renderLanes); + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } // Don't bubble properties in this case. - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + return workInProgress; + } - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; + } - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + if (nextDidTimeout && !prevDidTimeout) { + // If this subtree is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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(); + } + } + } { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + // TODO: Only schedule updates if these values are non equal, i.e. it changed. + if (nextDidTimeout || prevDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. In mutation mode, we also need the flag to + // *unhide* children that were previously hidden, so check if this + // is currently timed out, too. + workInProgress.flags |= Update; + } + } - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); + bubbleProperties(workInProgress); + + { + 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 doens't support type casting in combiation with the -= operator + workInProgress.treeBaseDuration -= + _primaryChildFragment2.treeBaseDuration; + } } } } - _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); - return updateMemoComponent( - current, - workInProgress, - _type2, - _resolvedProps3, - updateLanes, - renderLanes - ); + return null; } - case SimpleMemoComponent: { - return updateSimpleMemoComponent( - current, - workInProgress, - workInProgress.type, - workInProgress.pendingProps, - updateLanes, - renderLanes - ); - } + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(current, workInProgress); + + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } + + bubbleProperties(workInProgress); + return null; + + case ContextProvider: + // Pop provider fiber + var context = workInProgress.type._context; + popProvider(context, workInProgress); + bubbleProperties(workInProgress); + return null; case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + // 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 _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (isContextProvider(_Component)) { + popContext(workInProgress); + } - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); + bubbleProperties(workInProgress); + return null; } case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - case FundamentalComponent: { - break; - } + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + bubbleProperties(workInProgress); + return null; + } - case ScopeComponent: { - break; - } + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + 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); - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); - } - } + if (!cannotBeSuspended) { + var row = workInProgress.child; - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + while (row !== null) { + var suspended = findFirstSuspended(row); -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} + 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. -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} + var newThennables = suspended.updateQueue; -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; + 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. -{ - // 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; + workInProgress.subtreeFlags = NoFlags; + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - 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; - } + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); // Don't bubble properties in this case. - if (node === workInProgress) { - return; - } + return workInProgress.child; + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + row = row.sibling; + } + } - node = node.return; - } + 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. - node.sibling.return = node.return; - node = node.sibling; - } - }; + workInProgress.lanes = SomeRetryLane; - updateHostContainer = function(workInProgress) { - // Noop - }; + { + markSpawnedWork(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); - 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; + 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 (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. + var _newThennables = _suspended.updateQueue; - 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`. + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } + + cutOffTailIfNeeded(renderState, true); // This might have been modified. + + 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. + + workInProgress.lanes = SomeRetryLane; + + { + markSpawnedWork(SomeRetryLane); + } + } + } - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + 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.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 (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - if (updatePayload) { - markUpdate(workInProgress); - } - }; + renderState.last = renderedTail; + } + } - 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); - } - }; -} + 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. -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; + var suspenseContext = suspenseStackCursor.current; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + // Don't bubble properties in this case. - 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; + return next; } - break; + bubbleProperties(workInProgress); + return 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; + case ScopeComponent: { + break; + } - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); + var _nextState = workInProgress.memoizedState; + var nextIsHidden = _nextState !== null; - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (current !== null) { + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; - 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; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; + } // Don't bubble properties for hidden children. + + if ( + !nextIsHidden || + includesSomeLane(subtreeRenderLanes, OffscreenLane) || + (workInProgress.mode & ConcurrentMode) === NoMode + ) { + bubbleProperties(workInProgress); } - break; + return null; } } -} -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} +function unwindWork(workInProgress, renderLanes) { switch (workInProgress.tag) { - case IndeterminateComponent: - case LazyComponent: - case SimpleMemoComponent: - case FunctionComponent: - case ForwardRef: - case Fragment: - case Mode: - case Profiler: - case ContextConsumer: - case MemoComponent: - return null; - case ClassComponent: { var Component = workInProgress.type; @@ -15293,6 +16284,18 @@ function completeWork(current, workInProgress, renderLanes) { popContext(workInProgress); } + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } + + return workInProgress; + } + return null; } @@ -15300,2330 +16303,2393 @@ function completeWork(current, workInProgress, renderLanes) { popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var fiberRoot = workInProgress.stateNode; + var _flags = workInProgress.flags; - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); } - 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(); + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; + } - 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; + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } + + case SuspenseComponent: { + popSuspenseContext(workInProgress); + + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - updateHostContainer(workInProgress); return null; } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + return null; + } - 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. + case HostPortal: + popHostContainer(workInProgress); + return null; - return null; - } + case ContextProvider: + var context = workInProgress.type._context; + popProvider(context, workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + + return null; + + case CacheComponent: + return null; + + default: + return null; + } +} + +function unwindInterruptedWork(interruptedWork, renderLanes) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; + + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); + } - 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. + break; + } - var _wasHydrated = popHydrationState(); + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - 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. + case HostComponent: { + popHostContext(interruptedWork); + break; + } - if (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } + case HostPortal: + popHostContainer(interruptedWork); + break; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - return null; - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - case HostText: { - var newText = newProps; + case ContextProvider: + var context = interruptedWork.type._context; + popProvider(context, interruptedWork); + break; - 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. + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); - 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. - } + break; + } +} - var _rootContainerInstance = getRootHostContainer(); +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - var _currentHostContext = getHostContext(); +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - var _wasHydrated2 = popHydrationState(); +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - return null; + if (logError === false) { + return; } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; + var error = errorInfo.value; - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - return workInProgress; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - if (nextDidTimeout && !prevDidTimeout) { - // If this subtreee is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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(); - } - } - } + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - { - // TODO: Only schedule updates if these values are non equal, i.e. it changed. - if (nextDidTimeout || prevDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if this - // is currently timed out, too. - workInProgress.flags |= Update; - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper + } + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); + } +} - return null; - } +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(workInProgress); +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". - return null; + update.payload = { + element: null + }; + var error = errorInfo.value; - case ContextProvider: - // Pop provider fiber - popProvider(workInProgress); - return null; + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - 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; + return update; +} - if (isContextProvider(_Component)) { - popContext(workInProgress); - } +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - return null; - } + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - return null; + var inst = fiber.stateNode; + + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); } - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined - 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); + logCapturedError(fiber, errorInfo); + } - if (!cannotBeSuspended) { - var row = workInProgress.child; + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); - while (row !== null) { - var suspended = findFirstSuspended(row); + { + if (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { + error( + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" + ); + } + } + } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - 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. + return update; +} - var newThennables = suspended.updateQueue; +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; - 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 list before doing the second pass since that's now invalid. + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); - if (renderState.lastEffect === null) { - workInProgress.firstEffect = null; - } + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } - workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); + } +} - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); - return workInProgress.child; - } + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + // A legacy mode Suspense quirk, only relevant to hook components. - row = row.sibling; - } - } + var tag = sourceFiber.tag; - 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. + if ( + (sourceFiber.mode & BlockingMode) === NoMode && + (tag === FunctionComponent || + tag === ForwardRef || + tag === SimpleMemoComponent) + ) { + var currentSource = sourceFiber.alternate; - workInProgress.lanes = SomeRetryLane; + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; + } + } - { - markSpawnedWork(SomeRetryLane); - } - } + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. + + var _workInProgress = returnFiber; + + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; + + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; } 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); + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. + // + // If the suspense boundary suspended itself suspended, we don't have to + // do this trick because nothing was partially started. We can just + // directly do a second pass over the fallback in this render and + // pretend we meant to render that directly. - 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 ( + (_workInProgress.mode & BlockingMode) === NoMode && + _workInProgress !== returnFiber + ) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - var _newThennables = _suspended.updateQueue; + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - cutOffTailIfNeeded(renderState, true); // This might have been modified. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if ( - renderState.tail === null && - renderState.tailMode === "hidden" && - !renderedTail.alternate && - !getIsHydrating() // We don't cut it if we're hydrating. - ) { - // We need to delete the row we just rendered. - // Reset the effect list to what it was before we rendered this - // child. The nested children have already appended themselves. - var lastEffect = (workInProgress.lastEffect = - renderState.lastEffect); // Remove any effects that were appended after this point. + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (lastEffect !== null) { - lastEffect.nextEffect = null; - } // We're done. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - 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. + _workInProgress = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - workInProgress.lanes = SomeRetryLane; + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - { - markSpawnedWork(SomeRetryLane); - } - } - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; - 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; + do { + switch (workInProgress.tag) { + case HostRoot: { + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - renderState.last = renderedTail; - } + enqueueCapturedUpdate(workInProgress, _update); + return; } - 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.lastEffect = workInProgress.lastEffect; - 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. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - var suspenseContext = suspenseStackCursor.current; + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + var _lane = pickArbitraryLane(rootRenderLanes); - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - return next; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - return null; - } + enqueueCapturedUpdate(workInProgress, _update2); + return; + } - case FundamentalComponent: { - break; + break; } - case ScopeComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (current !== null) { - var _nextState = workInProgress.memoizedState; - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== null; - var nextIsHidden = _nextState !== null; +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; - } - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; +var nextEffect = null; - return null; - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); } +}; // Capture errors so they don't interrupt unmounting. +function safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance +) { { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, unmountError); + } } } -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; - - if (isContextProvider(Component)) { - popContext(workInProgress); - } - - var flags = workInProgress.flags; - - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; +function safelyDetachRef(current, nearestMountedAncestor) { + var ref = current.ref; - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + if (ref !== null) { + if (typeof ref === "function") { + { + { + invokeGuardedCallback(null, ref, null, null); } - return workInProgress; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, refError); + } } - - return null; + } else { + ref.current = null; } + } +} - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; - - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } - - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } +function safelyCallDestroy(current, nearestMountedAncestor, destroy) { + { + invokeGuardedCallback(null, destroy, null); - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, nearestMountedAncestor, error); } + } +} - case SuspenseComponent: { - popSuspenseContext(workInProgress); +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = prepareForCommit(root.containerInfo); + nextEffect = firstChild; + commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber - var _flags2 = workInProgress.flags; + var shouldFire = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = false; + focusedInstanceHandle = null; + return shouldFire; +} - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. +function commitBeforeMutationEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + var deletions = fiber.deletions; - return workInProgress; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var deletion = deletions[i]; + commitBeforeMutationEffectsDeletion(deletion); } - - return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var child = fiber.child; - return null; + if ( + (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && + child !== null + ) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitBeforeMutationEffects_complete(); } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - popProvider(workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - return null; - - default: - return null; } } -function unwindInterruptedWork(interruptedWork) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +function commitBeforeMutationEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - if (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitBeforeMutationEffectsOnFiber, + null, + fiber + ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - break; + resetCurrentFiber(); } - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var sibling = fiber.sibling; - case HostComponent: { - popHostContext(interruptedWork); - break; + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; - - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + nextEffect = fiber.return; + } +} - case ContextProvider: - popProvider(interruptedWork); - break; +function commitBeforeMutationEffectsOnFiber(finishedWork) { + var current = finishedWork.alternate; + var flags = finishedWork.flags; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); - break; + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + // Check to see if the focused element was inside of a hidden (Suspense) subtree. + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + finishedWork.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, finishedWork) && + doesFiberContain(finishedWork, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } } -} -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(finishedWork); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + break; + } -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + case ClassComponent: { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (logError === false) { - return; - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - var error = errorInfo.value; + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); + + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + + break; } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + case HostRoot: { + { + var root = finishedWork.stateNode; + clearContainer(root.containerInfo); + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); - } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + break; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + break; - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + default: { + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); + + resetCurrentFiber(); } } -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; +function commitBeforeMutationEffectsDeletion(deletion) { + // TODO (effects) It would be nice to avoid calling doesFiberContain() + // Maybe we can repurpose one of the subtreeFlags positions for this instead? + // Use it to store which part of the tree the focused instance is in? + // This assumes we can safely determine that instance during the "render" phase. + if (doesFiberContain(deletion, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } +} -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor +) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - update.payload = { - element: null - }; - var error = errorInfo.value; + do { + if ((effect.tag & flags) === flags) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + if (destroy !== undefined) { + safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); + } + } - return update; + effect = effect.next; + } while (effect !== firstEffect); + } } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; - - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var inst = fiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + { + var destroy = effect.destroy; - logCapturedError(fiber, errorInfo); - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum ); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - - return update; -} - -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; - - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); - - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); + effect = effect.next; + } while (effect !== firstEffect); } } -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes +function commitLayoutEffectOnFiber( + finishedRoot, + current, + finishedWork, + committedLanes ) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. - - sourceFiber.firstEffect = sourceFiber.lastEffect = null; - - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; - - if ((sourceFiber.mode & BlockingMode) === NoMode) { - // Reset the memoizedState to what it was before we attempted - // to render it. - var currentSource = sourceFiber.alternate; + if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; + break; } - } - - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. - - var _workInProgress = returnFiber; - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + case ClassComponent: { + var instance = finishedWork.stateNode; - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if ((_workInProgress.mode & BlockingMode) === NoMode) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. + var updateQueue = finishedWork.updateQueue; - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + commitUpdateQueue(finishedWork, updateQueue, instance); + } - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + break; + } - do { - switch (workInProgress.tag) { case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; + + if (_updateQueue !== null) { + var _instance = null; + + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; + + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - enqueueCapturedUpdate(workInProgress, _update); - return; + break; } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + } - var _lane = pickArbitraryLane(rootRenderLanes); + break; + } - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + case HostText: { + // We have no life-cycles associated with text. + break; + } - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); + case HostPortal: { + // We have no life-cycles associated with portals. + break; + } - enqueueCapturedUpdate(workInProgress, _update2); - return; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); + var phase = current === null ? "mount" : "update"; + + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + phase, + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } } break; + } + + case SuspenseComponent: { + break; + } + + case SuspenseListComponent: + case IncompleteClassComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + break; + + default: { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } } + } - workInProgress = workInProgress.return; - } while (workInProgress !== null); + { + if (finishedWork.flags & Ref) { + commitAttachRef(finishedWork); + } + } } -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; +function hideOrUnhideAllChildren(finishedWork, isHidden) { + { + // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + var node = finishedWork; -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + while (true) { + if (node.tag === HostComponent) { + var instance = node.stateNode; -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + if (isHidden) { + hideTextInstance(); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } else if ( + (node.tag === OffscreenComponent || + node.tag === LegacyHiddenComponent) && + node.memoizedState !== null && + node !== finishedWork + ); + else if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; + } - { - instance.componentWillUnmount(); - } -}; // Capture errors so they don't interrupt unmounting. + if (node === finishedWork) { + return; + } -function safelyCallComponentWillUnmount(current, instance) { - { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance - ); + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, unmountError); + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; } } } -function safelyDetachRef(current) { - var ref = current.ref; +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; + + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; + + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + if (typeof ref === "function") { { - { - invokeGuardedCallback(null, ref, null, null); - } - - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, refError); - } + ref(instanceToUse); } } else { - ref.current = null; + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } + } + + ref.current = instanceToUse; } } } -function safelyCallDestroy(current, destroy) { - { - invokeGuardedCallback(null, destroy, null); +function commitDetachRef(current) { + var currentRef = current.ref; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, error); + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); + } + } else { + currentRef.current = null; } } -} +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { +function commitUnmount( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + onCommitUnmount(current); + + switch (current.tag) { case FunctionComponent: case ForwardRef: + case MemoComponent: case SimpleMemoComponent: { - return; - } + var updateQueue = current.updateQueue; - case ClassComponent: { - if (finishedWork.flags & Snapshot) { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); + do { + var _effect = effect, + destroy = _effect.destroy, + tag = _effect.tag; + + if (destroy !== undefined) { + if ((tag & Layout) !== NoFlags$1) { + { + safelyCallDestroy(current, nearestMountedAncestor, destroy); + } } } - } - - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + effect = effect.next; + } while (effect !== firstEffect); + } + } - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + return; + } - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + case ClassComponent: { + safelyDetachRef(current, nearestMountedAncestor); + var instance = current.stateNode; - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount( + current, + nearestMountedAncestor, + instance + ); } return; } - case HostRoot: { + case HostComponent: { + safelyDetachRef(current, nearestMountedAncestor); + return; + } + + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. { - if (finishedWork.flags & Snapshot) { - var root = finishedWork.stateNode; - clearContainer(root.containerInfo); - } + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } return; } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types + case DehydratedFragment: { return; - } + } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + case ScopeComponent: { + return; + } } } -function commitHookEffectListUnmount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function commitNestedUnmounts( + finishedRoot, + root, + nearestMountedAncestor, + renderPriorityLevel +) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (true) { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. - do { - if ((effect.tag & tag) === tag) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + node.tag !== HostPortal + ) { + node.child.return = node; + node = node.child; + continue; + } - if (destroy !== undefined) { - destroy(); - } + if (node === root) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - effect = effect.next; - } while (effect !== firstEffect); + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } +} + +function detachFiberMutation(fiber) { + // Cut off the return pointer to disconnect it from the tree. + // This enables us to detect and warn against state updates on an unmounted component. + // It also prevents events from bubbling from within disconnected components. + // + // Ideally, we should also clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. + // This child itself will be GC:ed when the parent updates the next time. + // + // Note that we can't clear child or sibling pointers yet. + // They're needed for passive effects and for findDOMNode. + // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). + // + // Don't reset the alternate yet, either. We need that so we can detach the + // alternate's fields in the passive phase. Clearing the return pointer is + // sufficient for findDOMNode semantics. + fiber.return = null; +} + +function detachFiberAfterEffects(fiber) { + // Null out fields to improve GC for references that may be lingering (e.g. DevTools). + // Note that we already cleared the return pointer in detachFiberMutation(). + fiber.alternate = null; + fiber.child = null; + fiber.deletions = null; + fiber.dependencies = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.sibling = null; + fiber.stateNode = null; + fiber.updateQueue = null; + + { + fiber._debugOwner = null; } } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function getHostParentFiber(fiber) { + var parent = fiber.return; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + while (parent !== null) { + if (isHostParent(parent)) { + return parent; + } - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + parent = parent.return; + } - { - var destroy = effect.destroy; + { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; +function isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + fiber.tag === HostPortal + ); +} - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } +function getHostSibling(fiber) { + // We're going to search forward into the tree until we find a sibling host + // node. Unfortunately, if multiple insertions are done in a row we have to + // search past them. This leads to exponential search for the next sibling. + // TODO: Find a more efficient way to do this. + var node = fiber; - error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum - ); - } - } + siblings: while (true) { + // If we didn't find anything, let's try the next sibling. + while (node.sibling === null) { + if (node.return === null || isHostParent(node.return)) { + // If we pop out of the root or hit the parent the fiber we are the + // last sibling. + return null; } - effect = effect.next; - } while (effect !== firstEffect); - } -} - -function schedulePassiveEffects(finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; + node = node.return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + node.sibling.return = node.return; + node = node.sibling; - do { - var _effect = effect, - next = _effect.next, - tag = _effect.tag; + while ( + node.tag !== HostComponent && + node.tag !== HostText && + node.tag !== DehydratedFragment + ) { + // If it is not host node and, we might have a host node inside it. + // Try to search down until we find one. + if (node.flags & Placement) { + // If we don't have a child, try the siblings instead. + continue siblings; + } // If we don't have a child, try the siblings instead. + // We also skip portals because they are not part of this host tree. - if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); - enqueuePendingPassiveHookEffectMount(finishedWork, effect); + if (node.child === null || node.tag === HostPortal) { + continue siblings; + } else { + node.child.return = node; + node = node.child; } + } // Check if this host node is stable or about to be placed. - effect = next; - } while (effect !== firstEffect); + if (!(node.flags & Placement)) { + // Found it! + return node.stateNode; + } } } -function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - schedulePassiveEffects(finishedWork); - return; - } + var parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - case ClassComponent: { - var instance = finishedWork.stateNode; + switch (parentFiber.tag) { + case HostComponent: + parent = parentStateNode; + isContainer = false; + break; - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + case HostRoot: + parent = parentStateNode.containerInfo; + isContainer = true; + break; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + case HostPortal: + parent = parentStateNode.containerInfo; + isContainer = true; + break; + // eslint-disable-next-line-no-fallthrough - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); + } + } - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (parentFiber.flags & ContentReset) { + parentFiber.flags &= ~ContentReset; + } - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - var updateQueue = finishedWork.updateQueue; +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); + } + } else if (tag === HostPortal); + else { + var child = node.child; + + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; - commitUpdateQueue(finishedWork, updateQueue, instance); + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; } - - return; } + } +} - case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; +function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - if (_updateQueue !== null) { - var _instance = null; + if (isHost) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; + if (before) { + insertBefore(parent, stateNode, before); + } else { + appendChild(parent, stateNode); + } + } else if (tag === HostPortal); + else { + var child = node.child; - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; - commitUpdateQueue(finishedWork, _updateQueue, _instance); + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; } - - return; } + } +} - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. +function unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + var node = current; // Each iteration, currentParent is populated with node's host parent if not + // currentParentIsValid. - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - } + var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - return; - } + var currentParent; + var currentParentIsContainer; - case HostText: { - // We have no life-cycles associated with text. - return; - } + while (true) { + if (!currentParentIsValid) { + var parent = node.return; - case HostPortal: { - // We have no life-cycles associated with portals. - return; - } + findParent: while (true) { + if (!(parent !== null)) { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); + var parentStateNode = parent.stateNode; - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - current === null ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } - } + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; - return; - } + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; - case SuspenseComponent: { - return; - } + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + } - case SuspenseListComponent: - case IncompleteClassComponent: - case FundamentalComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - return; - } + parent = parent.return; + } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } -} + currentParentIsValid = true; + } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - { - // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. - var node = finishedWork; + if (node.tag === HostComponent || node.tag === HostText) { + commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the + // node from the tree. - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, node.stateNode); + } else { + removeChild(currentParent, node.stateNode); + } // Don't visit children because we already visited them. + } else if (node.tag === HostPortal) { + if (node.child !== null) { + // When we go into a portal, it becomes the parent to remove from. + // We will reassign it back when we pop the portal on the way up. + currentParent = node.stateNode.containerInfo; + currentParentIsContainer = true; // Visit children because portals might contain host components. - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); - } - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; + node.child.return = node; + node = node.child; + continue; + } + } else { + commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); - } - } else if ( - (node.tag === OffscreenComponent || - node.tag === LegacyHiddenComponent) && - node.memoizedState !== null && - node !== finishedWork - ); - else if (node.child !== null) { + if (node.child !== null) { node.child.return = node; node = node.child; continue; } + } - if (node === finishedWork) { + if (node === current) { + return; + } + + while (node.sibling === null) { + if (node.return === null || node.return === current) { return; } - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; - } + node = node.return; - node = node.return; + if (node.tag === HostPortal) { + // When we go out of the portal, we need to restore the parent. + // Since we don't keep a stack of them, we will search for it. + currentParentIsValid = false; } - - node.sibling.return = node.return; - node = node.sibling; } + + node.sibling.return = node.return; + node = node.sibling; } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; - - if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; - - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag - - if (typeof ref === "function") { - { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); - } - } - - ref.current = instanceToUse; - } +function commitDeletion( + finishedRoot, + current, + nearestMountedAncestor, + renderPriorityLevel +) { + { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current, nearestMountedAncestor); } -} -function commitDetachRef(current) { - var currentRef = current.ref; + var alternate = current.alternate; + detachFiberMutation(current); - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; - } + if (alternate !== null) { + detachFiberMutation(alternate); } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount(finishedRoot, current, renderPriorityLevel) { - onCommitUnmount(current); +} - switch (current.tag) { +function commitWork(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: case MemoComponent: case SimpleMemoComponent: { - var updateQueue = current.updateQueue; + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListUnmount( + Layout | HasEffect, + finishedWork, + finishedWork.return + ); + } - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case ClassComponent: { + return; + } + + case HostComponent: { + var instance = finishedWork.stateNode; + + if (instance != null) { + // Commit the work prepared earlier. + var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. - do { - var _effect2 = effect, - destroy = _effect2.destroy, - tag = _effect2.tag; + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. - if (destroy !== undefined) { - if ((tag & Passive$1) !== NoFlags$1) { - enqueuePendingPassiveHookEffectUnmount(current, effect); - } else { - { - safelyCallDestroy(current, destroy); - } - } - } + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; - effect = effect.next; - } while (effect !== firstEffect); + if (updatePayload !== null) { + commitUpdate(instance, updatePayload, type, oldProps, newProps); } } return; } - case ClassComponent: { - safelyDetachRef(current); - var instance = current.stateNode; - - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount(current, instance); + case HostText: { + if (!(finishedWork.stateNode !== null)) { + throw Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); } + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldText = current !== null ? current.memoizedProps : newText; + commitTextUpdate(textInstance, oldText, newText); return; } - case HostComponent: { - safelyDetachRef(current); + case HostRoot: { return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - unmountHostComponents(finishedRoot, current); - } + case Profiler: { + return; + } + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); return; } - case FundamentalComponent: { + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); return; } - case DehydratedFragment: { + case IncompleteClassComponent: { return; } case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + hideOrUnhideAllChildren(finishedWork, isHidden); return; } } + + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } } -function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - while (true) { - commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. + if (newState !== null) { + markCommitTimeOfFallback(); - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - node.tag !== HostPortal - ) { - node.child.return = node; - node = node.child; - continue; + { + // Hide the Offscreen component that contains the primary children. TODO: + // Ideally, this effect would have been scheduled on the Offscreen fiber + // itself. That's how unhiding works: the Offscreen component schedules an + // effect on itself. However, in this case, the component didn't complete, + // so the fiber was never added to the effect list in the normal path. We + // could have appended it to the effect list in the Suspense component's + // second pass, but doing it this way is less complicated. This would be + // simpler if we got rid of the effect list and traversed the tree, like + // we're planning to do. + var primaryChildParent = finishedWork.child; + hideOrUnhideAllChildren(primaryChildParent, true); } + } +} - if (node === root) { - return; - } +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - node = node.return; + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); } - node.sibling.return = node.return; - node = node.sibling; - } -} + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); -function detachFiberMutation(fiber) { - // Cut off the return pointers to disconnect it from the tree. Ideally, we - // should clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. This child - // itself will be GC:ed when the parent updates the next time. - // Note: we cannot null out sibling here, otherwise it can cause issues - // with findDOMNode and how it requires the sibling field to carry out - // traversal in a later effect. See PR #16820. We now clear the sibling - // field after effects, see: detachFiberAfterEffects. - // - // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. - // It may be required if the current component is an error boundary, - // and one of its descendants throws while unmounting a passive effect. - fiber.alternate = null; - fiber.child = null; - fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.return = null; - fiber.updateQueue = null; + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); + } + } - { - fiber._debugOwner = null; + retryCache.add(wakeable); + wakeable.then(retry, retry); + } + }); } -} +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. -function getHostParentFiber(fiber) { - var parent = fiber.return; +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - while (parent !== null) { - if (isHostParent(parent)) { - return parent; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } - - parent = parent.return; } - { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + return false; } -function isHostParent(fiber) { - return ( - fiber.tag === HostComponent || - fiber.tag === HostRoot || - fiber.tag === HostPortal - ); +function commitResetTextContent(current) { + resetTextContent(current.stateNode); } -function getHostSibling(fiber) { - // We're going to search forward into the tree until we find a sibling host - // node. Unfortunately, if multiple insertions are done in a row we have to - // search past them. This leads to exponential search for the next sibling. - // TODO: Find a more efficient way to do this. - var node = fiber; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + nextEffect = firstChild; + commitMutationEffects_begin(root, renderPriorityLevel); +} - siblings: while (true) { - // If we didn't find anything, let's try the next sibling. - while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { - // If we pop out of the root or hit the parent the fiber we are the - // last sibling. - return null; - } +function commitMutationEffects_begin(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - node = node.return; - } + var deletions = fiber.deletions; - node.sibling.return = node.return; - node = node.sibling; + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var childToDelete = deletions[i]; - while ( - node.tag !== HostComponent && - node.tag !== HostText && - node.tag !== DehydratedFragment - ) { - // If it is not host node and, we might have a host node inside it. - // Try to search down until we find one. - if (node.flags & Placement) { - // If we don't have a child, try the siblings instead. - continue siblings; - } // If we don't have a child, try the siblings instead. - // We also skip portals because they are not part of this host tree. + { + invokeGuardedCallback( + null, + commitDeletion, + null, + root, + childToDelete, + fiber, + renderPriorityLevel + ); - if (node.child === null || node.tag === HostPortal) { - continue siblings; - } else { - node.child.return = node; - node = node.child; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(childToDelete, fiber, error); + } + } } - } // Check if this host node is stable or about to be placed. + } - if (!(node.flags & Placement)) { - // Found it! - return node.stateNode; + var child = fiber.child; + + if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitMutationEffects_complete(root, renderPriorityLevel); } } } -function commitPlacement(finishedWork) { - var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - - var parent; - var isContainer; - var parentStateNode = parentFiber.stateNode; - - switch (parentFiber.tag) { - case HostComponent: - parent = parentStateNode; - isContainer = false; - break; - - case HostRoot: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - - case HostPortal: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - - case FundamentalComponent: - - // eslint-disable-next-line-no-fallthrough +function commitMutationEffects_complete(root, renderPriorityLevel) { + while (nextEffect !== null) { + var fiber = nextEffect; - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitMutationEffectsOnFiber, + null, + fiber, + root, + renderPriorityLevel ); + + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); } - } - if (parentFiber.flags & ContentReset) { - parentFiber.flags &= ~ContentReset; - } + var sibling = fiber.sibling; - var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); + nextEffect = fiber.return; } } -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; +function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { + var flags = finishedWork.flags; - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (flags & ContentReset) { + commitResetTextContent(finishedWork); + } - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); + if (flags & Ref) { + var current = finishedWork.alternate; + + if (current !== null) { + commitDetachRef(current); } - } else if (tag === HostPortal); - else { - var child = node.child; + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + var primaryFlags = flags & (Placement | Update | Hydrating); - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; - } + switch (primaryFlags) { + case Placement: { + commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + finishedWork.flags &= ~Placement; + break; } - } -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; + case PlacementAndUpdate: { + // Placement + commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. - if (isHost || enableFundamentalAPI) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + finishedWork.flags &= ~Placement; // Update - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); + var _current = finishedWork.alternate; + commitWork(_current, finishedWork); + break; } - } else if (tag === HostPortal); - else { - var child = node.child; - if (child !== null) { - insertOrAppendPlacementNode(child, before, parent); - var sibling = child.sibling; + case Hydrating: { + finishedWork.flags &= ~Hydrating; + break; + } - while (sibling !== null) { - insertOrAppendPlacementNode(sibling, before, parent); - sibling = sibling.sibling; - } + case HydratingAndUpdate: { + finishedWork.flags &= ~Hydrating; // Update + + var _current2 = finishedWork.alternate; + commitWork(_current2, finishedWork); + break; + } + + case Update: { + var _current3 = finishedWork.alternate; + commitWork(_current3, finishedWork); + break; } } } -function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { - // We only have the top Fiber that was deleted but we need to recurse down its - // children to find all the terminal nodes. - var node = current; // Each iteration, currentParent is populated with node's host parent if not - // currentParentIsValid. - - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - - var currentParent; - var currentParentIsContainer; +function commitLayoutEffects(finishedWork, root, committedLanes) { + nextEffect = finishedWork; + commitLayoutEffects_begin(finishedWork, root, committedLanes); +} - while (true) { - if (!currentParentIsValid) { - var parent = node.return; +function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + } + } +} - var parentStateNode = parent.stateNode; +function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { + while (nextEffect !== null) { + var fiber = nextEffect; - switch (parent.tag) { - case HostComponent: - currentParent = parentStateNode; - currentParentIsContainer = false; - break findParent; + if ((fiber.flags & LayoutMask) !== NoFlags) { + var current = fiber.alternate; - case HostRoot: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitLayoutEffectOnFiber, + null, + root, + current, + fiber, + committedLanes + ); - case HostPortal: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); } - parent = parent.return; + resetCurrentFiber(); } + } - currentParentIsValid = true; + if (fiber === subtreeRoot) { + nextEffect = null; + return; } - if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the - // node from the tree. + var sibling = fiber.sibling; - if (currentParentIsContainer) { - removeChildFromContainer(currentParent, node.stateNode); - } else { - removeChild(currentParent, node.stateNode); - } // Don't visit children because we already visited them. - } else if (node.tag === HostPortal) { - if (node.child !== null) { - // When we go into a portal, it becomes the parent to remove from. - // We will reassign it back when we pop the portal on the way up. - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = true; // Visit children because portals might contain host components. + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - node.child.return = node; - node = node.child; - continue; - } - } else { - commitUnmount(finishedRoot, node); // Visit children because we may find more host components below. + nextEffect = fiber.return; + } +} - if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } - } +function commitPassiveMountEffects(root, finishedWork) { + nextEffect = finishedWork; + commitPassiveMountEffects_begin(finishedWork, root); +} - if (node === current) { - return; +function commitPassiveMountEffects_begin(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; + var firstChild = fiber.child; + + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { + ensureCorrectReturnPointer(firstChild, fiber); + nextEffect = firstChild; + } else { + commitPassiveMountEffects_complete(subtreeRoot, root); } + } +} - while (node.sibling === null) { - if (node.return === null || node.return === current) { - return; - } +function commitPassiveMountEffects_complete(subtreeRoot, root) { + while (nextEffect !== null) { + var fiber = nextEffect; - node = node.return; + if ((fiber.flags & Passive) !== NoFlags) { + { + setCurrentFiber(fiber); + invokeGuardedCallback( + null, + commitPassiveMountOnFiber, + null, + root, + fiber + ); - if (node.tag === HostPortal) { - // When we go out of the portal, we need to restore the parent. - // Since we don't keep a stack of them, we will search for it. - currentParentIsValid = false; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(fiber, fiber.return, error); + } + + resetCurrentFiber(); } } - node.sibling.return = node.return; - node = node.sibling; - } -} + if (fiber === subtreeRoot) { + nextEffect = null; + return; + } -function commitDeletion(finishedRoot, current, renderPriorityLevel) { - { - // Recursively delete all host nodes from the parent. - // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current); - } + var sibling = fiber.sibling; - var alternate = current.alternate; - detachFiberMutation(current); + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - if (alternate !== null) { - detachFiberMutation(alternate); + nextEffect = fiber.return; } } -function commitWork(current, finishedWork) { +function commitPassiveMountOnFiber(finishedRoot, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case MemoComponent: case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. { - commitHookEffectListUnmount(Layout | HasEffect, finishedWork); + commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); } - return; + break; } + } +} - case ClassComponent: { - return; - } +function commitPassiveUnmountEffects(firstChild) { + nextEffect = firstChild; + commitPassiveUnmountEffects_begin(); +} - case HostComponent: { - var instance = finishedWork.stateNode; +function commitPassiveUnmountEffects_begin() { + while (nextEffect !== null) { + var fiber = nextEffect; + var child = fiber.child; - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + if ((nextEffect.flags & ChildDeletion) !== NoFlags) { + var deletions = fiber.deletions; - var oldProps = current !== null ? current.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + if (deletions !== null) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + nextEffect = fiberToDelete; + commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + fiberToDelete, + fiber + ); // Now that passive effects have been processed, it's safe to detach lingering pointers. - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + var alternate = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); - if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + if (alternate !== null) { + detachFiberAfterEffects(alternate); + } } - } - - return; - } - - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } - - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. - var oldText = current !== null ? current.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); - return; + nextEffect = fiber; + } } - case HostRoot: { - return; + if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffects_complete(); } + } +} - case Profiler: { - return; - } +function commitPassiveUnmountEffects_complete() { + while (nextEffect !== null) { + var fiber = nextEffect; - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + if ((fiber.flags & Passive) !== NoFlags) { + setCurrentFiber(fiber); + commitPassiveUnmountOnFiber(fiber); + resetCurrentFiber(); } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + var sibling = fiber.sibling; - case IncompleteClassComponent: { + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; return; } - case FundamentalComponent: { - break; - } + nextEffect = fiber.return; + } +} - case ScopeComponent: { - break; - } +function commitPassiveUnmountOnFiber(finishedWork) { + { + finishedWork.flags &= ~PassiveUnmountPendingDev; + var alternate = finishedWork.alternate; - case OffscreenComponent: - case LegacyHiddenComponent: { - var newState = finishedWork.memoizedState; - var isHidden = newState !== null; - hideOrUnhideAllChildren(finishedWork, isHidden); - return; + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; } } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount( + Passive$1 | HasEffect, + finishedWork, + finishedWork.return + ); + } + + break; + } } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( + deletedSubtreeRoot, + nearestMountedAncestor +) { + while (nextEffect !== null) { + var fiber = nextEffect; // Deletion effects fire in parent -> child order + // TODO: Check if fiber has a PassiveStatic flag - if (newState !== null) { - markCommitTimeOfFallback(); + setCurrentFiber(fiber); + commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); + resetCurrentFiber(); + var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag - { - // Hide the Offscreen component that contains the primary children. TODO: - // Ideally, this effect would have been scheduled on the Offscreen fiber - // itself. That's how unhiding works: the Offscreen component schedules an - // effect on itself. However, in this case, the component didn't complete, - // so the fiber was never added to the effect list in the normal path. We - // could have appended it to the effect list in the Suspense component's - // second pass, but doing it this way is less complicated. This would be - // simpler if we got rid of the effect list and traversed the tree, like - // we're planning to do. - var primaryChildParent = finishedWork.child; - hideOrUnhideAllChildren(primaryChildParent, true); + if (child !== null) { + ensureCorrectReturnPointer(child, fiber); + nextEffect = child; + } else { + commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot + ); } } } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; - - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; +function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( + deletedSubtreeRoot +) { + while (nextEffect !== null) { + var fiber = nextEffect; - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + if (fiber === deletedSubtreeRoot) { + nextEffect = null; + return; } - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + var sibling = fiber.sibling; - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } + if (sibling !== null) { + ensureCorrectReturnPointer(sibling, fiber.return); + nextEffect = sibling; + return; + } - retryCache.add(wakeable); - wakeable.then(retry, retry); - } - }); + nextEffect = fiber.return; } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. +} -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; +function commitPassiveUnmountInsideDeletedTreeOnFiber( + current, + nearestMountedAncestor +) { + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + { + commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); + } - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + break; } } - - return false; } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); +var didWarnWrongReturnPointer = false; + +function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { + { + if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { + didWarnWrongReturnPointer = true; + + error( + "Internal React error: Return pointer is inconsistent " + "with parent." + ); + } + } // TODO: Remove this assignment once we're confident that it won't break + // anything, by checking the warning logs for the above invariant + + fiber.return = expectedReturnFiber; } var COMPONENT_TYPE = 0; @@ -17705,8 +18771,7 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; -var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -17725,16 +18790,13 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } -var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; +var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority$1; +var pendingPassiveEffectsRenderPriority = NoPriority; var pendingPassiveEffectsLanes = NoLanes; -var pendingPassiveHookEffectsMount = []; -var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -17752,13 +18814,10 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventWipLanes = NoLanes; -var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -17783,63 +18842,41 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all - // updates at the same priority within the same event. To do this, the inputs - // to the algorithm must be the same. For example, we use the `renderLanes` - // to avoid choosing a lane that is already in the middle of rendering. - // - // However, the "included" lanes could be mutated in between updates in the - // same event, like if you perform an update inside `flushSync`. Or any other - // code path that might call `prepareFreshStack`. - // - // The trick we use is to cache the first of each of these inputs within an - // event. Then reset the cached values once we can be sure the event is over. - // Our heuristic for that is whenever we enter a concurrent work loop. - // - // We'll do the same for `currentEventPendingLanes` below. - - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventPendingLanes !== NoLanes) { - currentEventPendingLanes = - mostRecentlyUpdatedRoot !== null - ? mostRecentlyUpdatedRoot.pendingLanes - : NoLanes; + if (currentEventTransitionLane === NoLane) { + currentEventTransitionLane = claimNextTransitionLane(); } - return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); + return currentEventTransitionLane; } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. - // This couples React to the Scheduler internals, so we're replacing it - // with the currentUpdateLanePriority above. As an example of how this - // could be problematic, if we're not inside `Scheduler.runWithPriority`, - // then we'll get the priority of the current running Scheduler task, - // which is probably not what we want. + var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be + // the update lane priority, but for now we're also checking for discrete + // updates and falling back to the scheduler priority. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority$1 + schedulerPriority === UserBlockingPriority ) { - lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); + lane = findUpdateLane(InputDiscreteLanePriority); } else { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - - lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); + { + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + lane = findUpdateLane(schedulerLanePriority); + } } return lane; @@ -17855,16 +18892,12 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority$1 + return getCurrentPriorityLevel() === ImmediatePriority ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - if (currentEventWipLanes === NoLanes) { - currentEventWipLanes = workInProgressRootIncludedLanes; - } - - return findRetryLane(currentEventWipLanes); + return claimNextRetryLane(); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -17937,8 +18970,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority$1 || - priorityLevel === ImmediatePriority$1) + (priorityLevel === UserBlockingPriority || + priorityLevel === ImmediatePriority) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -17951,13 +18984,9 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } // We use this when assigning a lane for a transition inside - // `requestUpdateLane`. We assume it's the same as the root being updated, - // since in the common case of a single root app it probably is. If it's not - // the same root, then it's not a huge deal, we just might batch more stuff - // together more than necessary. + } - mostRecentlyUpdatedRoot = root; + return root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -17979,7 +19008,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child expiration time. + } // Walk the parent path to the root and update the child lanes. var node = sourceFiber; var parent = sourceFiber.return; @@ -18008,6 +19037,20 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } +} + +function isInterleavedUpdate(fiber, lane) { + return ( + // TODO: Optimize slightly by comparing to root that fiber belongs to. + // Requires some refactoring. Not a big deal though since it's rare for + // concurrent apps to have more than a single root. + workInProgressRoot !== null && + (fiber.mode & BlockingMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), + // then don't treat this as an interleaved update. This pattern is + // accompanied by a warning but we haven't fully deprecated it yet. We can + // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. + deferRenderPhaseUpdateToNextBatch + ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -18031,22 +19074,36 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); - root.callbackNode = null; - root.callbackPriority = NoLanePriority; } + root.callbackNode = null; + root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - if (existingCallbackNode !== null) { - var existingCallbackPriority = root.callbackPriority; + var existingCallbackPriority = root.callbackPriority; - if (existingCallbackPriority === newCallbackPriority) { - // The priority hasn't changed. We can reuse the existing task. Exit. - return; - } // The priority changed. Cancel the existing callback. We'll schedule a new - // one below. + if (existingCallbackPriority === newCallbackPriority) { + { + // If we're going to re-use an existing task, it needs to exist. + // Assume that discrete update microtasks are non-cancellable and null. + // TODO: Temporary until we confirm this warning is not fired. + if ( + existingCallbackNode == null && + existingCallbackPriority !== InputDiscreteLanePriority && + existingCallbackPriority !== SyncLanePriority + ) { + error( + "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." + ); + } + } // The priority hasn't changed. We can reuse the existing task. Exit. + + return; + } + if (existingCallbackNode != null) { + // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -18055,12 +19112,11 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - newCallbackNode = scheduleSyncCallback( - performSyncWorkOnRoot.bind(null, root) - ); + scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); + newCallbackNode = null; } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority$1, + ImmediatePriority, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -18078,12 +19134,11 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root) { - // Since we know we're in a React event, we can clear the current +function performConcurrentWorkOnRoot(root, didTimeout) { // event time. The next update will compute a new event time. + currentEventTime = NoTimestamp; - currentEventWipLanes = NoLanes; - currentEventPendingLanes = NoLanes; + currentEventTransitionLane = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -18113,24 +19168,22 @@ function performConcurrentWorkOnRoot(root) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; + } // TODO: We only check `didTimeout` defensively, to account for a Scheduler + // bug we're still investigating. Once the bug in Scheduler is fixed, + // we can remove this, since we track expiration ourselves. + + if (didTimeout) { + // Something expired. Flush synchronously until there's no expired + // work left. + markRootExpired(root, lanes); // This will schedule a synchronous callback. + + ensureRootIsScheduled(root, now()); + return null; } var exitStatus = renderRootConcurrent(root, lanes); - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // So we'll throw out the current work and restart. - prepareFreshStack(root, NoLanes); - } else if (exitStatus !== RootIncomplete) { + if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -18322,26 +19375,9 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - - if ( - includesSomeLane( - workInProgressRootIncludedLanes, - workInProgressRootUpdatedLanes - ) - ) { - // The render included lanes that were updated during the render phase. - // For example, when unhiding a hidden tree, we include all the lanes - // that were previously skipped when the tree was hidden. That set of - // lanes is a superset of the lanes we started rendering with. - // - // Note that this only happens when part of the tree is rendered - // concurrently. If the whole tree is rendered synchronously, then there - // are no interleaved events. - lanes = getNextLanes(root, lanes); - exitStatus = renderRootSync(root, lanes); - } } else { - lanes = getNextLanes(root, NoLanes); + lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + exitStatus = renderRootSync(root, lanes); } @@ -18419,7 +19455,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); + return runWithPriority(ImmediatePriority, fn.bind(null, a)); } else { return undefined; } @@ -18475,6 +19511,7 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; + enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -18798,47 +19835,6 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } - - resetChildLanes(completedWork); - - if ( - returnFiber !== null && // Do not append effects to parents if a sibling failed to complete - (returnFiber.flags & Incomplete) === NoFlags - ) { - // Append all the effects of the subtree and this fiber onto the effect - // list of the parent. The completion order of the children affects the - // side-effect order. - if (returnFiber.firstEffect === null) { - returnFiber.firstEffect = completedWork.firstEffect; - } - - if (completedWork.lastEffect !== null) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork.firstEffect; - } - - returnFiber.lastEffect = completedWork.lastEffect; - } // If this fiber had side-effects, we append it AFTER the children's - // side-effects. We can perform certain side-effects earlier if needed, - // by doing multiple passes over the effect list. We don't want to - // schedule our own side-effect on our own list because if end up - // reusing children we'll schedule this effect onto itself since we're - // at the end. - - var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect - // list. PerformedWork effect is read by React DevTools but shouldn't be - // committed. - - if (flags > PerformedWork) { - if (returnFiber.lastEffect !== null) { - returnFiber.lastEffect.nextEffect = completedWork; - } else { - returnFiber.firstEffect = completedWork; - } - - returnFiber.lastEffect = completedWork; - } - } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -18871,9 +19867,10 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its effect list. - returnFiber.firstEffect = returnFiber.lastEffect = null; + // Mark the parent fiber as incomplete and clear its subtree flags. returnFiber.flags |= Incomplete; + returnFiber.subtreeFlags = NoFlags; + returnFiber.deletions = null; } } @@ -18895,88 +19892,10 @@ function completeUnitOfWork(unitOfWork) { } } -function resetChildLanes(completedWork) { - if ( - // TODO: Move this check out of the hot path by moving `resetChildLanes` - // to switch statement in `completeWork`. - (completedWork.tag === LegacyHiddenComponent || - completedWork.tag === OffscreenComponent) && - completedWork.memoizedState !== null && - !includesSomeLane(subtreeRenderLanes, OffscreenLane) && - (completedWork.mode & ConcurrentMode) !== NoLanes - ) { - // The children of this component are hidden. Don't bubble their - // expiration times. - return; - } - - var newChildLanes = NoLanes; // 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; // 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. - - var shouldBubbleActualDurations = - completedWork.alternate === null || - completedWork.child !== completedWork.alternate.child; - var child = completedWork.child; - - while (child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(child.lanes, child.childLanes) - ); - - if (shouldBubbleActualDurations) { - actualDuration += child.actualDuration; - } - - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } - - var isTimedOutSuspense = - completedWork.tag === SuspenseComponent && - completedWork.memoizedState !== null; - - if (isTimedOutSuspense) { - // Don't count time spent in a timed out Suspense subtree as part of the base duration. - var primaryChildFragment = completedWork.child; - - if (primaryChildFragment !== null) { - treeBaseDuration -= primaryChildFragment.treeBaseDuration; - } - } - - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; - - while (_child !== null) { - newChildLanes = mergeLanes( - newChildLanes, - mergeLanes(_child.lanes, _child.childLanes) - ); - _child = _child.sibling; - } - } - - completedWork.childLanes = newChildLanes; -} - function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority$1, + ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -19016,7 +19935,8 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; // Update the first and last pending times on this root. The new first + root.callbackNode = null; + root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -19038,90 +19958,62 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // Get the list of effects. - - var firstEffect; - - if (finishedWork.flags > PerformedWork) { - // A fiber's effect list consists only of its children, not itself. So if - // the root has an effect, we need to add it to the end of the list. The - // resulting list is the set that would belong to the root's parent, if it - // had one; that is, all the effects in the tree including the root. - if (finishedWork.lastEffect !== null) { - finishedWork.lastEffect.nextEffect = finishedWork; - firstEffect = finishedWork.firstEffect; - } else { - firstEffect = finishedWork; - } - } else { - // There is no effect on the root. - firstEffect = finishedWork.firstEffect; - } + } // If there are pending passive effects, schedule a callback to process them. + // Do this as early as possible, so it is queued before anything else that + // might get scheduled in the commit phase. (See #16714.) + // TODO: Delete all other places that schedule the passive effect callback + // They're redundant. - if (firstEffect !== null) { + if ( + (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || + (finishedWork.flags & PassiveMask) !== NoFlags + ) { + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority, function() { + flushPassiveEffects(); + return null; + }); + } + } // Check if there are any effects in the whole tree. + // TODO: This is left over from the effect list implementation, where we had + // to check for the existence of `firstEffect` to satsify Flow. I think the + // only other reason this optimization exists is because it affects profiling. + // Reconsider whether this is necessary. + + var subtreeHasEffects = + (finishedWork.subtreeFlags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + var rootHasEffect = + (finishedWork.flags & + (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== + NoFlags; + + if (subtreeHasEffects || rootHasEffect) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass - // of the effect list for each phase: all mutation effects come before all - // layout effects, and so on. - // The first phase a "before mutation" phase. We use this phase to read the - // state of the host tree right before we mutate it. This is where - // getSnapshotBeforeUpdate is called. - - focusedInstanceHandle = prepareForCommit(root.containerInfo); - shouldFireAfterActiveInstanceBlur = false; - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitBeforeMutationEffects, null); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); // We no longer need to track the active instance fiber + // of the effect list for each phase: all mutation effects come before all + // layout effects, and so on. + // The first phase a "before mutation" phase. We use this phase to read the + // state of the host tree right before we mutate it. This is where + // getSnapshotBeforeUpdate is called. - focusedInstanceHandle = null; + var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( + root, + finishedWork + ); { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } // The next phase is the mutation phase, where we mutate the host tree. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback( - null, - commitMutationEffects, - null, - root, - renderPriorityLevel - ); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error = clearCaughtError(); + } - captureCommitPhaseError(nextEffect, _error); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); + commitMutationEffects(root, renderPriorityLevel, finishedWork); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -19129,29 +20021,8 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read - // the host tree after it's been mutated. The idiomatic use case for this is - // layout, but class component lifecycles also fire here for legacy reasons. - - nextEffect = firstEffect; - - do { - { - invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - - if (hasCaughtError()) { - if (!(nextEffect !== null)) { - throw Error("Should be working on an effect."); - } - - var _error2 = clearCaughtError(); - - captureCommitPhaseError(nextEffect, _error2); - nextEffect = nextEffect.nextEffect; - } - } - } while (nextEffect !== null); - nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an + commitLayoutEffects(finishedWork, root, lanes); // opportunity to paint. requestPaint(); @@ -19181,22 +20052,6 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; - } else { - // We are done with the effect chain at this point so let's clear the - // nextEffect pointers to assist with GC. If we have passive effects, we'll - // clear this in flushPassiveEffects. - nextEffect = firstEffect; - - while (nextEffect !== null) { - var nextNextEffect = nextEffect.nextEffect; - nextEffect.nextEffect = null; - - if (nextEffect.flags & Deletion) { - detachFiberAfterEffects(nextEffect); - } - - nextEffect = nextNextEffect; - } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -19234,9 +20089,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (remainingLanes === SyncLane) { - // Count the number of times the root synchronously re-renders without + if (includesSomeLane(remainingLanes, SyncLane)) { // finishing. If there are too many, it indicates an infinite update loop. + if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -19254,9 +20109,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var _error3 = firstUncaughtError; + var error = firstUncaughtError; firstUncaughtError = null; - throw _error3; + throw error; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -19272,156 +20127,14 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } -function commitBeforeMutationEffects() { - while (nextEffect !== null) { - var current = nextEffect.alternate; - - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - if ((nextEffect.flags & Deletion) !== NoFlags) { - if (doesFiberContain(nextEffect, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } - } else { - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - nextEffect.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } - } - - var flags = nextEffect.flags; - - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(nextEffect); - commitBeforeMutationLifeCycles(current, nextEffect); - resetCurrentFiber(); - } - - if ((flags & Passive) !== NoFlags) { - // If there are passive effects, schedule a callback to flush at - // the earliest opportunity. - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } - } - - nextEffect = nextEffect.nextEffect; - } -} - -function commitMutationEffects(root, renderPriorityLevel) { - // TODO: Should probably move the bulk of this function to commitWork. - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & ContentReset) { - commitResetTextContent(nextEffect); - } - - if (flags & Ref) { - var current = nextEffect.alternate; - - if (current !== null) { - commitDetachRef(current); - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - - var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); - - switch (primaryFlags) { - case Placement: { - commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - nextEffect.flags &= ~Placement; - break; - } - - case PlacementAndUpdate: { - // Placement - commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - - nextEffect.flags &= ~Placement; // Update - - var _current = nextEffect.alternate; - commitWork(_current, nextEffect); - break; - } - - case Hydrating: { - nextEffect.flags &= ~Hydrating; - break; - } - - case HydratingAndUpdate: { - nextEffect.flags &= ~Hydrating; // Update - - var _current2 = nextEffect.alternate; - commitWork(_current2, nextEffect); - break; - } - - case Update: { - var _current3 = nextEffect.alternate; - commitWork(_current3, nextEffect); - break; - } - - case Deletion: { - commitDeletion(root, nextEffect); - break; - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - -function commitLayoutEffects(root, committedLanes) { - while (nextEffect !== null) { - setCurrentFiber(nextEffect); - var flags = nextEffect.flags; - - if (flags & (Update | Callback)) { - var current = nextEffect.alternate; - commitLifeCycles(root, current, nextEffect); - } - - { - if (flags & Ref) { - commitAttachRef(nextEffect); - } - } - - resetCurrentFiber(); - nextEffect = nextEffect.nextEffect; - } -} - function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { + if (pendingPassiveEffectsRenderPriority !== NoPriority) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority$1 - ? NormalPriority$1 + pendingPassiveEffectsRenderPriority > NormalPriority + ? NormalPriority : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority$1; + pendingPassiveEffectsRenderPriority = NoPriority; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -19430,42 +20143,6 @@ function flushPassiveEffects() { return false; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - - { - fiber.flags |= PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags |= PassiveUnmountPendingDev; - } - } - - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority$1, function() { - flushPassiveEffects(); - return null; - }); - } -} - -function invokePassiveEffectCreate(effect) { - var create = effect.create; - effect.destroy = create(); -} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -19487,97 +20164,9 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called - // before ANY passive effect create functions are called. - // Otherwise effects in sibling components might interfere with each other. - // e.g. a destroy function in one component may unintentionally override a ref - // value set by a create function in another component. - // Layout effects have the same constraint. - // First pass: Destroy stale passive effects. - - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - - for (var i = 0; i < unmountEffects.length; i += 2) { - var _effect = unmountEffects[i]; - var fiber = unmountEffects[i + 1]; - var destroy = _effect.destroy; - _effect.destroy = undefined; - - { - fiber.flags &= ~PassiveUnmountPendingDev; - var alternate = fiber.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } - } - - if (typeof destroy === "function") { - { - setCurrentFiber(fiber); - - { - invokeGuardedCallback(null, destroy, null); - } - - if (hasCaughtError()) { - if (!(fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var error = clearCaughtError(); - captureCommitPhaseError(fiber, error); - } - - resetCurrentFiber(); - } - } - } // Second pass: Create new passive effects. - - var mountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - - for (var _i = 0; _i < mountEffects.length; _i += 2) { - var _effect2 = mountEffects[_i]; - var _fiber = mountEffects[_i + 1]; - - { - setCurrentFiber(_fiber); - - { - invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); - } - - if (hasCaughtError()) { - if (!(_fiber !== null)) { - throw Error("Should be working on an effect."); - } - - var _error4 = clearCaughtError(); - - captureCommitPhaseError(_fiber, _error4); - } - - resetCurrentFiber(); - } - } // Note: This currently assumes there are no passive effects on the root fiber - // because the root is not part of its own effect list. - // This could change in the future. - - var effect = root.current.firstEffect; - - while (effect !== null) { - var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC - - effect.nextEffect = null; - - if (effect.flags & Deletion) { - detachFiberAfterEffects(effect); - } - - effect = nextNextEffect; - } + var prevInteractions = pushInteractions(root); + commitPassiveUnmountEffects(root.current); + commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects { popInteractions(prevInteractions); @@ -19634,19 +20223,23 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); return; } - var fiber = sourceFiber.return; + var fiber = null; + + { + fiber = sourceFiber.return; + } while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19657,7 +20250,7 @@ function captureCommitPhaseError(sourceFiber, error) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error, sourceFiber); + var errorInfo = createCapturedValue(error$1, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19667,24 +20260,6 @@ function captureCommitPhaseError(sourceFiber, error) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); - } else { - // This component has already been unmounted. - // We can't schedule any follow up work for the root because the fiber is already unmounted, - // but we can still call the log-only boundary so the error isn't swallowed. - // - // TODO This is only a temporary bandaid for the old reconciler fork. - // We can delete this special case once the new fork is merged. - if ( - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance) - ) { - try { - instance.componentDidCatch(error, errorInfo); - } catch (errorToIgnore) { - // TODO Ignore this error? Rethrow it? - // This is kind of an edge case. - } - } } return; @@ -19693,6 +20268,22 @@ function captureCommitPhaseError(sourceFiber, error) { fiber = fiber.return; } + + { + // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning + // will fire for errors that are thrown by destroy functions inside deleted + // trees. What it should instead do is propagate the error to the parent of + // the deleted tree. In the meantime, do not add this warning to the + // allowlist; this is only for our internal use. + error( + "Internal React error: Attempted to capture a commit phase error " + + "inside a detached tree. This indicates a bug in React. Likely " + + "causes include deleting the same fiber more than once, committing an " + + "already-finished tree, or an inconsistent return pointer.\n\n" + + "Error message:\n\n%s", + error$1 + ); + } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19745,6 +20336,8 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { + // TODO: Assign this to `suspenseState.retryLane`? to avoid + // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -19913,11 +20506,29 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } // If there are pending passive effects unmounts for this Fiber, - // we can assume that they would have prevented this update. + } - if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { - return; + if ((fiber.flags & PassiveStatic) !== NoFlags) { + var updateQueue = fiber.updateQueue; + + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; + + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if (effect.destroy !== undefined) { + if ((effect.tag & Passive$1) !== NoFlags$1) { + return; + } + } + + effect = effect.next; + } while (effect !== firstEffect); + } + } } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -20005,14 +20616,23 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. - // Rethrow this error instead of the original one. + var replayError = clearCaughtError(); - throw replayError; - } else { - // This branch is reachable if the render phase is impure. - throw originalError; - } + if ( + typeof replayError === "object" && + replayError !== null && + replayError._suppressLogging && + typeof originalError === "object" && + originalError !== null && + !originalError._suppressLogging + ) { + // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. + originalError._suppressLogging = true; + } + } // We always throw the original error in case the second render pass is not idempotent. + // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + + throw originalError; } }; } @@ -20101,7 +20721,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { "act(() => ...);\n\n" + "// for react-test-renderer:\n" + // Break up imports to avoid accidentally parsing them as dependencies. "import TestRenderer fr" + - "om react-test-renderer';\n" + + "om 'react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" @@ -20119,7 +20739,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - (fiber.mode & StrictMode) !== NoMode && + (fiber.mode & StrictLegacyMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { @@ -20299,7 +20919,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -20321,7 +20941,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } finally { @@ -20343,7 +20963,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority$1, function() { + scheduleCallback(ImmediatePriority, function() { throw error; }); } @@ -20362,11 +20982,6 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; -function detachFiberAfterEffects(fiber) { - fiber.sibling = null; - fiber.stateNode = null; -} - var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20843,9 +21458,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.nextEffect = null; - this.firstEffect = null; - this.lastEffect = null; + this.subtreeFlags = NoFlags; + this.deletions = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20972,11 +21586,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effect list is no longer valid. + workInProgress.flags = NoFlags; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; + workInProgress.subtreeFlags = NoFlags; + workInProgress.deletions = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -20986,8 +21599,10 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } + } // Reset all effects except static ones. + // Static effects are not specific to a render. + workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -21044,13 +21659,10 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect tag but keep any Placement tags, since that's something + // Reset the effect flags but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. - workInProgress.nextEffect = null; - workInProgress.firstEffect = null; - workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -21058,6 +21670,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; + workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -21074,7 +21687,12 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; + workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in + // `createWorkInProgress`. Nothing reads this until the complete phase, + // currently, but it might in the future, and we should be consistent. + + workInProgress.subtreeFlags = current.subtreeFlags; + workInProgress.deletions = null; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -21101,13 +21719,33 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag) { +function createHostRootFiber(tag, strictModeLevelOverride) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode | StrictMode; + mode = ConcurrentMode | BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else if (tag === BlockingRoot) { - mode = BlockingMode | StrictMode; + mode = BlockingMode; + + if (strictModeLevelOverride !== null) { + if (strictModeLevelOverride >= 1) { + mode |= StrictLegacyMode; + } + } else { + { + mode |= StrictLegacyMode; + } + } } else { mode = NoMode; } @@ -21158,8 +21796,16 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; - mode |= StrictMode; + fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. + + var level = + pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. + // It is explicitly not supported to lower a mode with nesting, only to increase it. + + if (level >= 1) { + mode |= StrictLegacyMode; + } + break; case REACT_PROFILER_TYPE: @@ -21181,6 +21827,10 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough + case REACT_CACHE_TYPE: + + // eslint-disable-next-line no-fallthrough + default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -21409,9 +22059,8 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.nextEffect = source.nextEffect; - target.firstEffect = source.firstEffect; - target.lastEffect = source.lastEffect; + target.subtreeFlags = source.subtreeFlags; + target.deletions = source.deletions; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -21478,13 +22127,27 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { +function createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag); + var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; + + { + var _initialState = { + element: null + }; + uninitializedFiber.memoizedState = _initialState; + } + initializeUpdateQueue(uninitializedFiber); return root; } @@ -21558,7 +22221,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictMode) { + if (hostFiber.mode & StrictLegacyMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -21568,7 +22231,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictMode) { + if (fiber.mode & StrictLegacyMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -21607,8 +22270,20 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { - return createFiberRoot(containerInfo, tag, hydrate); +function createContainer( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride +) { + return createFiberRoot( + containerInfo, + tag, + hydrate, + hydrationCallbacks, + strictModeLevelOverride + ); } function updateContainer(element, container, parentComponent, callback) { { @@ -21673,7 +22348,12 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - scheduleUpdateOnFiber(current$1, lane, eventTime); + var root = scheduleUpdateOnFiber(current$1, lane, eventTime); + + if (root !== null) { + entangleTransitions(root, current$1, lane); + } + return lane; } function getPublicRootInstance(container) { @@ -22354,11 +23034,12 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false); + root = createContainer(containerTag, LegacyRoot, false, null, null); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); + updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + return getPublicRootInstance(root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index ccced617800599..8d91437ab93175 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_222 = { +var injectedNamesToPlugins$jscomp$inline_213 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_222 = { } } }, - isOrderingDirty$jscomp$inline_223 = !1, - pluginName$jscomp$inline_224; -for (pluginName$jscomp$inline_224 in injectedNamesToPlugins$jscomp$inline_222) + isOrderingDirty$jscomp$inline_214 = !1, + pluginName$jscomp$inline_215; +for (pluginName$jscomp$inline_215 in injectedNamesToPlugins$jscomp$inline_213) if ( - injectedNamesToPlugins$jscomp$inline_222.hasOwnProperty( - pluginName$jscomp$inline_224 + injectedNamesToPlugins$jscomp$inline_213.hasOwnProperty( + pluginName$jscomp$inline_215 ) ) { - var pluginModule$jscomp$inline_225 = - injectedNamesToPlugins$jscomp$inline_222[pluginName$jscomp$inline_224]; + var pluginModule$jscomp$inline_216 = + injectedNamesToPlugins$jscomp$inline_213[pluginName$jscomp$inline_215]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_224) || - namesToPlugins[pluginName$jscomp$inline_224] !== - pluginModule$jscomp$inline_225 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_215) || + namesToPlugins[pluginName$jscomp$inline_215] !== + pluginModule$jscomp$inline_216 ) { - if (namesToPlugins[pluginName$jscomp$inline_224]) + if (namesToPlugins[pluginName$jscomp$inline_215]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_224 + + pluginName$jscomp$inline_215 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_224 - ] = pluginModule$jscomp$inline_225; - isOrderingDirty$jscomp$inline_223 = !0; + pluginName$jscomp$inline_215 + ] = pluginModule$jscomp$inline_216; + isOrderingDirty$jscomp$inline_214 = !0; } } -isOrderingDirty$jscomp$inline_223 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_214 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1139,7 +1139,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1158,6 +1159,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1184,6 +1186,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1217,7 +1221,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1305,19 +1309,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1567,60 +1566,382 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 256; + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1766,296 +2087,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null, - Scheduler_now = Scheduler.unstable_now; -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; + injectedHook = null; +function onCommitRoot(root) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + injectedHook.onCommitFiberRoot( + rendererID, + root, + void 0, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2135,10 +2177,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2189,13 +2231,14 @@ function readContext(context, observedBits) { } return context._currentValue; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2221,14 +2264,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2297,111 +2358,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2457,7 +2517,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2468,7 +2529,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2478,7 +2540,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2626,24 +2689,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2675,16 +2736,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2699,7 +2760,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2813,15 +2883,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2856,15 +2918,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3070,43 +3124,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3284,7 +3333,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3436,10 +3485,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3464,22 +3514,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3519,7 +3580,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3549,25 +3610,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3594,6 +3643,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3619,6 +3670,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3667,7 +3720,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3675,10 +3728,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3763,33 +3816,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3846,6 +3921,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4021,7 +4098,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4097,14 +4174,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4121,30 +4199,39 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (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 ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, 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.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4154,7 +4241,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4179,7 +4266,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4354,7 +4441,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4362,7 +4449,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4376,7 +4463,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4397,7 +4484,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4441,18 +4528,21 @@ function pushHostRootContext(workInProgress) { 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 & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4469,7 +4559,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4481,9 +4573,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), + (workInProgress.lanes = 8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4509,8 +4603,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4537,8 +4634,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4561,7 +4661,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4594,13 +4694,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4610,26 +4711,22 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4654,8 +4751,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4665,16 +4761,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4683,9 +4777,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4708,7 +4802,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4729,8 +4823,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4752,19 +4845,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4774,25 +4859,23 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - 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; + 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 null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4839,16 +4922,40 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$64 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), + for (var lastTailNode$62 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$64 + null === lastTailNode$62 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$64.sibling = null); + : (lastTailNode$62.sibling = null); } } +function bubbleProperties(completedWork) { + var didBailout = + null !== completedWork.alternate && + completedWork.alternate.child === completedWork.child, + newChildLanes = 0, + subtreeFlags = 0; + if (didBailout) + for (var child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags & 131072), + (subtreeFlags |= child$63.flags & 131072), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + else + for (child$63 = completedWork.child; null !== child$63; ) + (newChildLanes |= child$63.lanes | child$63.childLanes), + (subtreeFlags |= child$63.subtreeFlags), + (subtreeFlags |= child$63.flags), + (child$63.return = completedWork), + (child$63 = child$63.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4862,76 +4969,80 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + 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(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + 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) @@ -4951,27 +5062,27 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -4986,82 +5097,92 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), - (renderLanes = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (updatePayload = rootContainerInstance.alternate), + (renderLanes = newProps), + (type = current), + (renderLanes.flags &= 131074), + (updatePayload = renderLanes.alternate), null === updatePayload - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = renderLanes), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null)) - : ((rootContainerInstance.childLanes = - updatePayload.childLanes), - (rootContainerInstance.lanes = updatePayload.lanes), - (rootContainerInstance.child = updatePayload.child), - (rootContainerInstance.memoizedProps = + ? ((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 = updatePayload.subtreeFlags), + (renderLanes.deletions = null), + (renderLanes.memoizedProps = updatePayload.memoizedProps), - (rootContainerInstance.memoizedState = + (renderLanes.memoizedState = updatePayload.memoizedState), - (rootContainerInstance.updateQueue = - updatePayload.updateQueue), - (rootContainerInstance.type = updatePayload.type), - (renderLanes = updatePayload.dependencies), - (rootContainerInstance.dependencies = - null === renderLanes + (renderLanes.updateQueue = updatePayload.updateQueue), + (renderLanes.type = updatePayload.type), + (type = updatePayload.dependencies), + (renderLanes.dependencies = + null === type ? null : { - lanes: renderLanes.lanes, - firstContext: renderLanes.firstContext + lanes: type.lanes, + firstContext: type.firstContext })), (newProps = newProps.sibling); push( @@ -5072,78 +5193,74 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5158,8 +5275,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null; case 3: popHostContainer(); @@ -5167,11 +5284,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5179,8 +5296,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) : null ); case 19: @@ -5188,10 +5305,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5264,140 +5383,150 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$81 = finishedRoot.create; - finishedRoot.destroy = create$81(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$81 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$81; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$81 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$81, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$80 = effect.create; + effect.destroy = create$80(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5457,7 +5586,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5474,26 +5603,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5501,26 +5628,34 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5555,7 +5690,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5671,7 +5806,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5709,12 +5848,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5741,18 +5881,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5763,7 +5903,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5785,42 +5930,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + var instance = finishedWork.stateNode; + if (null != instance) { + var newProps = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5858,32 +5992,207 @@ function commitWork(current, finishedWork) { ); return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); +} +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); + } +} +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + firstChild = renderPriorityLevel.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + unmountHostComponents(root, childToDelete, renderPriorityLevel); + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, renderPriorityLevel, error); + } + } + firstChild = renderPriorityLevel.child; + if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + try { + var flags = renderPriorityLevel.flags; + if (flags & 256) { + var current = renderPriorityLevel.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + break; + case 6: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 2048: + renderPriorityLevel.flags &= -2049; + break; + case 2052: + renderPriorityLevel.flags &= -2049; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 4: + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + } + } catch (error) { + captureCommitPhaseError( + renderPriorityLevel, + renderPriorityLevel.return, + error + ); + } + firstChild = renderPriorityLevel.sibling; + if (null !== firstChild) { + firstChild.return = renderPriorityLevel.return; + nextEffect = firstChild; + break; + } + nextEffect = renderPriorityLevel.return; + } + } } -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); +function commitLayoutEffects(finishedWork) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork; null !== nextEffect; ) { + firstChild = nextEffect; + if (0 !== (firstChild.flags & 324)) { + var current = firstChild.alternate; + try { + if (0 !== (firstChild.flags & 68)) + switch (firstChild.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, firstChild); + break; + case 1: + var instance = firstChild.stateNode; + if (firstChild.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + firstChild.elementType === firstChild.type + ? current.memoizedProps + : resolveDefaultProps( + firstChild.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = firstChild.updateQueue; + null !== updateQueue && + commitUpdateQueue(firstChild, updateQueue, instance); + break; + case 3: + var updateQueue$81 = firstChild.updateQueue; + if (null !== updateQueue$81) { + current = null; + if (null !== firstChild.child) + switch (firstChild.child.tag) { + case 5: + current = firstChild.child.stateNode; + break; + case 1: + current = firstChild.child.stateNode; + } + commitUpdateQueue(firstChild, updateQueue$81, current); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (firstChild.flags & 256) { + current = void 0; + var ref = firstChild.ref; + if (null !== ref) { + var instance$jscomp$0 = firstChild.stateNode; + switch (firstChild.tag) { + case 5: + current = instance$jscomp$0; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + } catch (error) { + captureCommitPhaseError(firstChild, firstChild.return, error); + } + } + if (firstChild === fiber) { + nextEffect = null; + break; + } + current = firstChild.sibling; + if (null !== current) { + current.return = firstChild.return; + nextEffect = current; + break; + } + nextEffect = firstChild.return; + } } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; -} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -5895,30 +6204,22 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -5928,30 +6229,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -5982,7 +6275,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6007,15 +6300,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$7] = + expirationTimes[index$6] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6030,45 +6323,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6079,16 +6369,22 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - var exitStatus = lanes; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); + didTimeout = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== exitStatus + workInProgressRootRenderLanes !== didTimeout ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, exitStatus); + prepareFreshStack(root, didTimeout); do try { workLoopConcurrent(); @@ -6101,19 +6397,17 @@ function performConcurrentWorkOnRoot(root) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6121,7 +6415,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6131,9 +6425,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -6144,7 +6438,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6152,13 +6446,13 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - prevDispatcher = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevExecutionContext && (prevExecutionContext = index$6); + var index$5 = 31 - clz32(lanes); + prevDispatcher = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > prevExecutionContext && (prevExecutionContext = index$5); lanes &= ~prevDispatcher; } lanes = prevExecutionContext; @@ -6204,9 +6498,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } @@ -6214,17 +6508,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6243,11 +6532,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6287,7 +6571,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6297,10 +6581,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6336,15 +6639,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6355,15 +6661,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { - var nextState = workInProgress$76.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { + var nextState = workInProgress$75.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$76.memoizedProps; + var props = workInProgress$75.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6375,16 +6681,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$76.updateQueue; + var wakeables = workInProgress$75.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$76.updateQueue = updateQueue; + workInProgress$75.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$76.mode & 2)) { - workInProgress$76.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$75.mode & 1) && + workInProgress$75 !== returnFiber + ) { + workInProgress$75.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6415,12 +6724,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$76.flags |= 8192; - workInProgress$76.lanes = thrownValue; + workInProgress$75.flags |= 16384; + workInProgress$75.lanes = thrownValue; break a; } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6429,47 +6738,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$76 = returnFiber; + workInProgress$75 = returnFiber; do { - switch (workInProgress$76.tag) { + switch (workInProgress$75.tag) { case 3: root = value; - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$77 = createRootErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$76 = createRootErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$77); + enqueueCapturedUpdate(workInProgress$75, update$76); break a; case 1: root = value; - var ctor = workInProgress$76.type, - instance = workInProgress$76.stateNode; + var ctor = workInProgress$75.type, + instance = workInProgress$75.stateNode; if ( - 0 === (workInProgress$76.flags & 64) && + 0 === (workInProgress$75.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$76.flags |= 8192; + workInProgress$75.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$76.lanes |= thrownValue; - var update$80 = createClassErrorUpdate( - workInProgress$76, + workInProgress$75.lanes |= thrownValue; + var update$79 = createClassErrorUpdate( + workInProgress$75, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$76, update$80); + enqueueCapturedUpdate(workInProgress$75, update$79); break a; } } - workInProgress$76 = workInProgress$76.return; - } while (null !== workInProgress$76); + workInProgress$75 = workInProgress$75.return; + } while (null !== workInProgress$75); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6530,47 +6839,25 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - current = completeWork(current, completedWork, subtreeRenderLanes); - if (null !== current) { - workInProgress = current; - return; - } - current = completedWork; + if (0 === (completedWork.flags & 8192)) { if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) + ((current = completeWork(current, completedWork, subtreeRenderLanes)), + null !== current) ) { - for (var newChildLanes = 0, child = current.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (child = child.sibling); - current.childLanes = newChildLanes; + workInProgress = current; + return; } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6591,7 +6878,8 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork; + var finishedWork = root.finishedWork, + lanes = root.finishedLanes; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6600,174 +6888,48 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; - executionContext |= 32; - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; - nextEffect = remainingLanes; - do - try { - for (eventTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - expirationTimes = nextEffect; - unmountHostComponents(eventTimes, expirationTimes); - var alternate = expirationTimes.alternate; - detachFiberMutation(expirationTimes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$88) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$88); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$89) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$89); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; - requestPaint(); - executionContext = remainingLanes$jscomp$0; - } else root.current = finishedWork; - if (rootDoesHavePassiveEffects) - (rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (renderPriorityLevel = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((flags$jscomp$0 = nextEffect), - (flags$jscomp$0.sibling = null), - (flags$jscomp$0.stateNode = null)), - (nextEffect = renderPriorityLevel); + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes + ? ((remainingLanes = executionContext), + (executionContext |= 32), + (ReactCurrentOwner$2.current = null), + commitBeforeMutationEffects(root, finishedWork), + commitMutationEffects(root, renderPriorityLevel, finishedWork), + (root.current = finishedWork), + commitLayoutEffects(finishedWork, root, lanes), + requestPaint(), + (executionContext = remainingLanes)) + : (root.current = finishedWork); + rootDoesHavePassiveEffects && + ((rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 1 === remainingLanes + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - void 0, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6778,30 +6940,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6813,24 +6951,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6839,40 +6959,103 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$94 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$94.destroy; - effect$94.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$94 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$98 = effect$94.create; - effect$94.destroy = create$98(); - } catch (error$99) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$99); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (create$98 = root.current.firstEffect; null !== create$98; ) - (root = create$98.nextEffect), - (create$98.nextEffect = null), - create$98.flags & 8 && - ((create$98.sibling = null), (create$98.stateNode = null)), - (create$98 = root); + for (nextEffect = root = root.current; null !== nextEffect; ) + if ( + ((fiber = nextEffect), + (child = fiber.child), + 0 !== (fiber.subtreeFlags & 1040) && null !== child) + ) + (child.return = fiber), (nextEffect = child); + else + a: for (fiber = root; null !== nextEffect; ) { + child = nextEffect; + if (0 !== (child.flags & 1024)) + try { + switch (child.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, child); + } + } catch (error) { + captureCommitPhaseError(child, child.return, error); + } + if (child === fiber) { + nextEffect = null; + break a; + } + deletions = child.sibling; + if (null !== deletions) { + deletions.return = child.return; + nextEffect = deletions; + break a; + } + nextEffect = child.return; + } executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -6887,42 +7070,50 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6934,7 +7125,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6947,14 +7138,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6970,78 +7160,83 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - 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.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - 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, + 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, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + 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 ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.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 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 + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7053,22 +7248,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7078,8 +7273,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7090,9 +7285,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7104,28 +7299,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7134,7 +7329,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7143,7 +7338,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7152,8 +7347,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7161,7 +7356,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7169,32 +7364,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7205,19 +7400,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7257,16 +7451,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7303,27 +7497,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7335,15 +7523,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7353,20 +7540,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7374,16 +7565,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7391,20 +7582,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7412,28 +7604,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7451,11 +7643,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7465,8 +7657,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7498,8 +7690,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7537,9 +7729,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null)); + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7574,15 +7766,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7769,7 +7964,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -7808,10 +8004,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_908 = { + devToolsConfig$jscomp$inline_959 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7826,11 +8022,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1115 = { - bundleType: devToolsConfig$jscomp$inline_908.bundleType, - version: devToolsConfig$jscomp$inline_908.version, - rendererPackageName: devToolsConfig$jscomp$inline_908.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_908.rendererConfig, +var internals$jscomp$inline_1242 = { + bundleType: devToolsConfig$jscomp$inline_959.bundleType, + version: devToolsConfig$jscomp$inline_959.version, + rendererPackageName: devToolsConfig$jscomp$inline_959.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_959.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7845,7 +8041,7 @@ var internals$jscomp$inline_1115 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_908.findFiberByHostInstance || + devToolsConfig$jscomp$inline_959.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7854,16 +8050,16 @@ var internals$jscomp$inline_1115 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1116 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1243 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1116.isDisabled && - hook$jscomp$inline_1116.supportsFiber + !hook$jscomp$inline_1243.isDisabled && + hook$jscomp$inline_1243.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1116.inject( - internals$jscomp$inline_1115 + (rendererID = hook$jscomp$inline_1243.inject( + internals$jscomp$inline_1242 )), - (injectedHook = hook$jscomp$inline_1116); + (injectedHook = hook$jscomp$inline_1243); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -7912,10 +8108,11 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var uninitializedFiber = createFiber(3, null, null, 0); - root.current = uninitializedFiber; - uninitializedFiber.stateNode = root; - initializeUpdateQueue(uninitializedFiber); + var JSCompiler_inline_result = createFiber(3, null, null, 0); + root.current = JSCompiler_inline_result; + JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; + initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 7937b1e922259d..680b703d37e6b2 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_226 = { +var injectedNamesToPlugins$jscomp$inline_219 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ var injectedNamesToPlugins$jscomp$inline_226 = { } } }, - isOrderingDirty$jscomp$inline_227 = !1, - pluginName$jscomp$inline_228; -for (pluginName$jscomp$inline_228 in injectedNamesToPlugins$jscomp$inline_226) + isOrderingDirty$jscomp$inline_220 = !1, + pluginName$jscomp$inline_221; +for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) if ( - injectedNamesToPlugins$jscomp$inline_226.hasOwnProperty( - pluginName$jscomp$inline_228 + injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( + pluginName$jscomp$inline_221 ) ) { - var pluginModule$jscomp$inline_229 = - injectedNamesToPlugins$jscomp$inline_226[pluginName$jscomp$inline_228]; + var pluginModule$jscomp$inline_222 = + injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_228) || - namesToPlugins[pluginName$jscomp$inline_228] !== - pluginModule$jscomp$inline_229 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || + namesToPlugins[pluginName$jscomp$inline_221] !== + pluginModule$jscomp$inline_222 ) { - if (namesToPlugins[pluginName$jscomp$inline_228]) + if (namesToPlugins[pluginName$jscomp$inline_221]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_228 + + pluginName$jscomp$inline_221 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_228 - ] = pluginModule$jscomp$inline_229; - isOrderingDirty$jscomp$inline_227 = !0; + pluginName$jscomp$inline_221 + ] = pluginModule$jscomp$inline_222; + isOrderingDirty$jscomp$inline_220 = !0; } } -isOrderingDirty$jscomp$inline_227 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1140,7 +1140,8 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131; + REACT_LEGACY_HIDDEN_TYPE = 60131, + REACT_CACHE_TYPE = 60132; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1159,6 +1160,7 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); + REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1185,6 +1187,8 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; + case REACT_CACHE_TYPE: + return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1218,7 +1222,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 1026) && (nearestMounted = node.return), + 0 !== (node.flags & 2050) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1306,19 +1310,14 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - if (!parent) return null; - for (var node = parent; ; ) { - if (5 === node.tag || 6 === node.tag) return node; - if (node.child) (node.child.return = node), (node = node.child); - else { - if (node === parent) break; - for (; !node.sibling; ) { - if (!node.return || node.return === parent) return null; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } + return null !== parent ? findCurrentHostFiberImpl(parent) : null; +} +function findCurrentHostFiberImpl(node) { + if (5 === node.tag || 6 === node.tag) return node; + for (node = node.child; null !== node; ) { + var match = findCurrentHostFiberImpl(node); + if (null !== match) return match; + node = node.sibling; } return null; } @@ -1568,60 +1567,396 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( - this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps + mountSafeCallback_NOT_REALLY_SAFE(this, callback) ); - }; - return ReactNativeFiberHostComponent; -})(); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( + this._nativeTag, + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( + this._nativeTag, + this.viewConfig.uiViewClassName, + nativeProps + ); + }; + return ReactNativeFiberHostComponent; + })(), + Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs = Scheduler_now(), + now = + 1e4 > initialTimeMs + ? Scheduler_now + : function() { + return Scheduler_now() - initialTimeMs; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } +} +var nextTransitionLane = 512, + nextRetryLane = 8388608, + return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + switch (lanes & -lanes) { + case 1: + return (return_highestLanePriority = 15), 1; + case 2: + return (return_highestLanePriority = 14), 2; + case 4: + return (return_highestLanePriority = 13), 4; + case 8: + return (return_highestLanePriority = 12), 8; + case 16: + return (return_highestLanePriority = 11), 16; + case 32: + return (return_highestLanePriority = 10), 32; + case 64: + return (return_highestLanePriority = 9), 64; + case 128: + return (return_highestLanePriority = 8), 128; + case 256: + return (return_highestLanePriority = 7), 256; + case 512: + case 1024: + case 2048: + case 4096: + case 8192: + case 16384: + case 32768: + case 65536: + case 131072: + case 262144: + case 524288: + case 1048576: + case 2097152: + case 4194304: + return (return_highestLanePriority = 6), lanes & 8388096; + case 8388608: + case 16777216: + case 33554432: + case 67108864: + return (return_highestLanePriority = 5), lanes & 125829120; + case 134217728: + return (return_highestLanePriority = 4), 134217728; + case 268435456: + return (return_highestLanePriority = 3), 268435456; + case 536870912: + return (return_highestLanePriority = 2), 536870912; + case 1073741824: + return (return_highestLanePriority = 1), 1073741824; + default: + return (return_highestLanePriority = 8), lanes; + } +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + 0 !== expiredLanes + ? ((nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15)) + : ((expiredLanes = pendingLanes & 268435455), + 0 !== expiredLanes + ? ((pendingLanes = expiredLanes & ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))) + : ((pendingLanes &= ~suspendedLanes), + 0 !== pendingLanes + ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)))); + if (0 === nextLanes) return 0; + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + suspendedLanes = return_highestLanePriority; + if ( + nextLanePriority <= suspendedLanes || + (8 === nextLanePriority && 6 === suspendedLanes) + ) + return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (nextLanePriority = 31 - clz32(wipLanes)), + (suspendedLanes = 1 << nextLanePriority), + (nextLanes |= root[nextLanePriority]), + (wipLanes &= ~suspendedLanes); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return 8; + case 10: + return 32; + case 8: + return 128; + case 2: + return 536870912; + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + 536870912 !== updateLane && + ((root.suspendedLanes = 0), (root.pingedLanes = 0)); + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + remainingLanes = root.entanglements; + var eventTimes = root.eventTimes; + for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { + var index$8 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$8; + remainingLanes[index$8] = 0; + eventTimes[index$8] = -1; + root[index$8] = -1; + noLongerPendingLanes &= ~lane; + } +} +function markRootEntangled(root, entangledLanes) { + var rootEntangledLanes = (root.entangledLanes |= entangledLanes); + for (root = root.entanglements; rootEntangledLanes; ) { + var index$9 = 31 - clz32(rootEntangledLanes), + lane = 1 << index$9; + (lane & entangledLanes) | (root[index$9] & entangledLanes) && + (root[index$9] |= entangledLanes); + rootEntangledLanes &= ~lane; + } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_now$1 = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -1768,310 +2103,17 @@ function invalidateContextProvider(workInProgress, type, didChange) { } var rendererID = null, injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, - Scheduler_now = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now(); -var return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; - if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; - if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; - var inputDiscreteLanes = 24 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 12), inputDiscreteLanes; - if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; - inputDiscreteLanes = 192 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 10), inputDiscreteLanes; - if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; - inputDiscreteLanes = 3584 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 8), inputDiscreteLanes; - if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; - inputDiscreteLanes = 4186112 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 6), inputDiscreteLanes; - inputDiscreteLanes = 62914560 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 5), inputDiscreteLanes; - if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; - if (0 !== (lanes & 134217728)) - return (return_highestLanePriority = 3), 134217728; - inputDiscreteLanes = 805306368 & lanes; - if (0 !== inputDiscreteLanes) - return (return_highestLanePriority = 2), inputDiscreteLanes; - if (0 !== (1073741824 & lanes)) - return (return_highestLanePriority = 1), 1073741824; - return_highestLanePriority = 8; - return lanes; -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - if (0 !== expiredLanes) - (nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15); - else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { - var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; - 0 !== nonIdleUnblockedLanes - ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority))); - } else - (expiredLanes = pendingLanes & ~suspendedLanes), - 0 !== expiredLanes - ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)); - if (0 === nextLanes) return 0; - nextLanes = 31 - clz32(nextLanes); - nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - if (nextLanePriority <= return_highestLanePriority) return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (pendingLanes = 31 - clz32(wipLanes)), - (nextLanePriority = 1 << pendingLanes), - (nextLanes |= root[pendingLanes]), - (wipLanes &= ~nextLanePriority); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority, wipLanes) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return ( - (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority - ); - case 10: - return ( - (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), - 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority - ); - case 8: - return ( - (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), - 0 === lanePriority && - ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), - 0 === lanePriority && (lanePriority = 512)), - lanePriority - ); - case 2: - return ( - (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), - 0 === wipLanes && (wipLanes = 268435456), - wipLanes - ); - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - var higherPriorityLanes = updateLane - 1; - root.suspendedLanes &= higherPriorityLanes; - root.pingedLanes &= higherPriorityLanes; - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now$1 = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var fakeCallbackNode = {}, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs$1 = Scheduler_now$1(), - now = - 1e4 > initialTimeMs$1 - ? Scheduler_now$1 - : function() { - return Scheduler_now$1() - initialTimeMs$1; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; +function onCommitRoot(root, priorityLevel) { + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + 128 === (root.current.flags & 128) + ); + } catch (err) {} } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2151,10 +2193,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(providerFiber) { +function popProvider(context) { var currentValue = valueCursor.current; pop(valueCursor); - providerFiber.type._context._currentValue = currentValue; + context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2205,13 +2247,14 @@ function readContext(context, observedBits) { } return context._currentValue; } -var hasForceUpdate = !1; +var interleavedQueues = null, + hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null }, + shared: { pending: null, interleaved: null, lanes: 0 }, effects: null }; } @@ -2237,14 +2280,32 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; + null !== updateQueue && + ((updateQueue = updateQueue.shared), + null !== workInProgressRoot && 0 !== (fiber.mode & 1) + ? ((fiber = updateQueue.interleaved), + null === fiber + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [updateQueue]) + : interleavedQueues.push(updateQueue)) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.interleaved = update)) + : ((fiber = updateQueue.pending), + null === fiber + ? (update.next = update) + : ((update.next = fiber.next), (fiber.next = update)), + (updateQueue.pending = update))); +} +function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber) { - fiber = fiber.shared; - var pending = fiber.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - fiber.pending = update; + if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { + var queueLanes = fiber.lanes; + queueLanes &= root.pendingLanes; + lane |= queueLanes; + fiber.lanes = lane; + markRootEntangled(root, lane); } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2313,111 +2374,110 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - if (null !== current) { - current = current.updateQueue; - var currentLastBaseUpdate = current.lastBaseUpdate; - currentLastBaseUpdate !== lastBaseUpdate && - (null === currentLastBaseUpdate + null !== current && + ((current = current.updateQueue), + (pendingQueue = current.lastBaseUpdate), + pendingQueue !== lastBaseUpdate && + (null === pendingQueue ? (current.firstBaseUpdate = firstPendingUpdate) - : (currentLastBaseUpdate.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate)); - } + : (pendingQueue.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate))); } if (null !== firstBaseUpdate) { - currentLastBaseUpdate = queue.baseState; + var newState = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; + pendingQueue = firstBaseUpdate; do { - pendingQueue = firstBaseUpdate.lane; - var updateEventTime = firstBaseUpdate.eventTime; - if ((renderLanes & pendingQueue) === pendingQueue) { + var updateLane = pendingQueue.lane, + updateEventTime = pendingQueue.eventTime; + if ((renderLanes & updateLane) === updateLane) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = firstBaseUpdate; - pendingQueue = props; + update = pendingQueue; + updateLane = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - currentLastBaseUpdate = workInProgress.call( + newState = workInProgress.call( updateEventTime, - currentLastBaseUpdate, - pendingQueue + newState, + updateLane ); break a; } - currentLastBaseUpdate = workInProgress; + newState = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -8193) | 64; + workInProgress.flags = (workInProgress.flags & -16385) | 128; case 0: workInProgress = update.payload; - pendingQueue = + updateLane = "function" === typeof workInProgress - ? workInProgress.call( - updateEventTime, - currentLastBaseUpdate, - pendingQueue - ) + ? workInProgress.call(updateEventTime, newState, updateLane) : workInProgress; - if (null === pendingQueue || void 0 === pendingQueue) break a; - currentLastBaseUpdate = Object.assign( - {}, - currentLastBaseUpdate, - pendingQueue - ); + if (null === updateLane || void 0 === updateLane) break a; + newState = Object.assign({}, newState, updateLane); break a; case 2: hasForceUpdate = !0; } } - null !== firstBaseUpdate.callback && - ((workInProgress$jscomp$0.flags |= 32), - (pendingQueue = queue.effects), - null === pendingQueue - ? (queue.effects = [firstBaseUpdate]) - : pendingQueue.push(firstBaseUpdate)); + null !== pendingQueue.callback && + ((workInProgress$jscomp$0.flags |= 64), + (updateLane = queue.effects), + null === updateLane + ? (queue.effects = [pendingQueue]) + : updateLane.push(pendingQueue)); } else (updateEventTime = { eventTime: updateEventTime, - lane: pendingQueue, - tag: firstBaseUpdate.tag, - payload: firstBaseUpdate.payload, - callback: firstBaseUpdate.callback, + lane: updateLane, + tag: pendingQueue.tag, + payload: pendingQueue.payload, + callback: pendingQueue.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = currentLastBaseUpdate)) + (lastPendingUpdate = newState)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= pendingQueue); - firstBaseUpdate = firstBaseUpdate.next; - if (null === firstBaseUpdate) + (lastBaseUpdate |= updateLane); + pendingQueue = pendingQueue.next; + if (null === pendingQueue) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (firstBaseUpdate = pendingQueue.next), - (pendingQueue.next = null), - (queue.lastBaseUpdate = pendingQueue), + (updateLane = pendingQueue), + (pendingQueue = updateLane.next), + (updateLane.next = null), + (queue.lastBaseUpdate = updateLane), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = currentLastBaseUpdate); + null === current && (lastPendingUpdate = newState); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; + props = queue.shared.interleaved; + if (null !== props) { + queue = props; + do (lastBaseUpdate |= queue.lane), (queue = queue.next); + while (queue !== props); + } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; + workInProgress$jscomp$0.memoizedState = newState; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2473,7 +2533,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2484,7 +2545,8 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + payload = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== payload && entangleTransitions(payload, inst, lane); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2494,7 +2556,8 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - scheduleUpdateOnFiber(inst, lane, eventTime); + callback = scheduleUpdateOnFiber(inst, lane, eventTime); + null !== callback && entangleTransitions(callback, inst, lane); } }; function checkShouldComponentUpdate( @@ -2642,24 +2705,22 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw Error( + throw ((returnFiber = Object.prototype.toString.call(newChild)), + Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === Object.prototype.toString.call(newChild) + ("[object Object]" === returnFiber ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : newChild) + + : returnFiber) + "). If you meant to render a collection of children, use an array instead." - ); + )); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var last = returnFiber.lastEffect; - null !== last - ? ((last.nextEffect = childToDelete), - (returnFiber.lastEffect = childToDelete)) - : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); - childToDelete.nextEffect = null; - childToDelete.flags = 8; + var deletions = returnFiber.deletions; + null === deletions + ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) + : deletions.push(childToDelete); } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2691,16 +2752,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags = 2), lastPlacedIndex) + ? ((newFiber.flags |= 2), lastPlacedIndex) : newIndex ); - newFiber.flags = 2; + newFiber.flags |= 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags = 2); + (newFiber.flags |= 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2715,7 +2776,16 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - if (null !== current && current.elementType === element.type) + var elementType = element.type; + if (elementType === REACT_FRAGMENT_TYPE) + return updateFragment( + returnFiber, + current, + element.props.children, + lanes, + element.key + ); + if (null !== current && current.elementType === elementType) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2829,15 +2899,7 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - oldFiber, - newChild.props.children, - lanes, - key - ) - : updateElement(returnFiber, oldFiber, newChild, lanes) + ? updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2872,15 +2934,7 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - newChild.type === REACT_FRAGMENT_TYPE - ? updateFragment( - returnFiber, - existingChildren, - newChild.props.children, - lanes, - newChild.key - ) - : updateElement(returnFiber, existingChildren, newChild, lanes) + updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3086,43 +3140,38 @@ function ChildReconciler(shouldTrackSideEffects) { ) { if (isUnkeyedTopLevelFragment.key === isObject) { - switch (isUnkeyedTopLevelFragment.tag) { - case 7: - if (newChild.type === REACT_FRAGMENT_TYPE) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - break; - default: - if ( - isUnkeyedTopLevelFragment.elementType === newChild.type - ) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } + isObject = newChild.type; + if (isObject === REACT_FRAGMENT_TYPE) { + if (7 === isUnkeyedTopLevelFragment.tag) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + } else if (isUnkeyedTopLevelFragment.elementType === isObject) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3300,7 +3349,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 64)) return node; + if (0 !== (node.flags & 128)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3452,10 +3501,11 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - baseQueue = baseQueue.next; + pendingQueue = baseQueue.next; current = current.baseState; - var newBaseQueueLast = (baseFirst = pendingQueue = null), - update = baseQueue; + var newBaseQueueFirst = (baseFirst = null), + newBaseQueueLast = null, + update = pendingQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3480,22 +3530,33 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) + ? ((newBaseQueueFirst = newBaseQueueLast = clone), + (baseFirst = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== baseQueue); + } while (null !== update && update !== pendingQueue); null === newBaseQueueLast - ? (pendingQueue = current) - : (newBaseQueueLast.next = baseFirst); + ? (baseFirst = current) + : (newBaseQueueLast.next = newBaseQueueFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = pendingQueue; + hook.baseState = baseFirst; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } + reducer = queue.interleaved; + if (null !== reducer) { + baseQueue = reducer; + do + (pendingQueue = baseQueue.lane), + (currentlyRenderingFiber$1.lanes |= pendingQueue), + (workInProgressRootSkippedLanes |= pendingQueue), + (baseQueue = baseQueue.next); + while (baseQueue !== reducer); + } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3535,7 +3596,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3565,25 +3626,13 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - if (!objectIs(version, maybeNewVersion)) { - maybeNewVersion = getSnapshot(source._source); + objectIs(version, maybeNewVersion) || + ((maybeNewVersion = getSnapshot(source._source)), objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); - maybeNewVersion = root.mutableReadLanes; - root.entangledLanes |= maybeNewVersion; - for ( - var entanglements = root.entanglements, lanes = maybeNewVersion; - 0 < lanes; - - ) { - var index$13 = 31 - clz32(lanes), - lane = 1 << index$13; - entanglements[index$13] |= maybeNewVersion; - lanes &= ~lane; - } - } + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), + markRootEntangled(root, root.mutableReadLanes)); }, [getSnapshot, source, subscribe] ); @@ -3610,6 +3659,8 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3635,6 +3686,8 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3683,7 +3736,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - pushEffect(hookFlags, create, destroy, deps); + hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3691,10 +3744,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(516, 4, create, deps); + return mountEffectImpl(132096, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(516, 4, create, deps); + return updateEffectImpl(1024, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3779,33 +3832,55 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - pending = queue.pending; - null === pending - ? (update.next = update) - : ((update.next = pending.next), (pending.next = update)); - queue.pending = update; - pending = fiber.alternate; + alternate = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== pending && pending === currentlyRenderingFiber$1) + (null !== alternate && alternate === currentlyRenderingFiber$1) ) - didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; + (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), + (lane = queue.pending), + null === lane + ? (update.next = update) + : ((update.next = lane.next), (lane.next = update)), + (queue.pending = update); else { + if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { + var interleaved = queue.interleaved; + null === interleaved + ? ((update.next = update), + null === interleavedQueues + ? (interleavedQueues = [queue]) + : interleavedQueues.push(queue)) + : ((update.next = interleaved.next), (interleaved.next = update)); + queue.interleaved = update; + } else + (interleaved = queue.pending), + null === interleaved + ? (update.next = update) + : ((update.next = interleaved.next), (interleaved.next = update)), + (queue.pending = update); if ( 0 === fiber.lanes && - (null === pending || 0 === pending.lanes) && - ((pending = queue.lastRenderedReducer), null !== pending) + (null === alternate || 0 === alternate.lanes) && + ((alternate = queue.lastRenderedReducer), null !== alternate) ) try { var currentState = queue.lastRenderedState, - eagerState = pending(currentState, action); - update.eagerReducer = pending; + eagerState = alternate(currentState, action); + update.eagerReducer = alternate; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - scheduleUpdateOnFiber(fiber, lane, eventTime); + update = scheduleUpdateOnFiber(fiber, lane, eventTime); + 0 !== (lane & 8388096) && + null !== update && + ((fiber = queue.lanes), + (fiber &= update.pendingLanes), + (lane |= fiber), + (queue.lanes = lane), + markRootEntangled(update, lane)); } } var ContextOnlyDispatcher = { @@ -3862,6 +3937,8 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, + interleaved: null, + lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4052,7 +4129,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4128,14 +4205,15 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) - if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) - 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); - else + ) { + didReceiveUpdate = !1; + if (0 === (renderLanes & updateLanes)) return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); + 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); + } return updateFunctionComponent( current, workInProgress, @@ -4152,31 +4230,40 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 4)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes(workInProgress, renderLanes); - else if (0 !== (renderLanes & 1073741824)) - (workInProgress.memoizedState = { baseLanes: 0 }), - pushRenderLanes( - workInProgress, - null !== prevState ? prevState.baseLanes : renderLanes + if (0 === (workInProgress.mode & 2)) + (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= renderLanes); + else { + if (0 === (renderLanes & 1073741824)) + return ( + (current = + null !== prevState + ? prevState.baseLanes | renderLanes + : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { + baseLanes: current, + cachePool: null + }), + (workInProgress.updateQueue = null), + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= current), + null ); - else - return ( - (current = - null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { baseLanes: current }), - pushRenderLanes(workInProgress, 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.memoizedState = null)) : (nextProps = renderLanes), - pushRenderLanes(workInProgress, nextProps); + push(subtreeRenderLanesCursor, subtreeRenderLanes), + (subtreeRenderLanes |= nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4186,7 +4273,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 128; + workInProgress.flags |= 256; } function updateFunctionComponent( current, @@ -4211,7 +4298,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -517), + (workInProgress.flags &= -1029), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4386,7 +4473,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 256)) + (workInProgress.flags |= 512)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4394,7 +4481,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4408,7 +4495,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 256), + (workInProgress.flags |= 512), (nextProps = !1)); } return finishClassComponent( @@ -4429,7 +4516,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 64); + var didCaptureError = 0 !== (workInProgress.flags & 128); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4477,18 +4564,21 @@ function pushHostRootContext(workInProgress) { 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 & 64)) || + (JSCompiler_temp = 0 !== (workInProgress.flags & 128)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -65)) + ? ((showFallback = !0), (workInProgress.flags &= -129)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4505,7 +4595,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4517,10 +4609,12 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = { baseLanes: renderLanes }), + (workInProgress.child.memoizedState = mountSuspenseOffscreenState( + renderLanes + )), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608), current ); renderLanes = createFiberFromOffscreen( @@ -4546,8 +4640,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4574,8 +4671,11 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? { baseLanes: renderLanes } - : { baseLanes: suspenseContext.baseLanes | renderLanes }), + ? mountSuspenseOffscreenState(renderLanes) + : { + baseLanes: suspenseContext.baseLanes | renderLanes, + cachePool: null + }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4598,10 +4698,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && null !== progressedPrimaryFragment + 0 === (mode & 1) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 8 && + workInProgress.mode & 4 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4636,13 +4736,14 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 2) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); primaryChildren.return = workInProgress; primaryChildren.sibling = null; null !== current && - ((current.nextEffect = null), - (current.flags = 8), - (workInProgress.firstEffect = workInProgress.lastEffect = current)); + ((renderLanes = workInProgress.deletions), + null === renderLanes + ? ((workInProgress.deletions = [current]), (workInProgress.flags |= 16)) + : renderLanes.push(current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4652,33 +4753,27 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode, - currentPrimaryChildFragment = current.child; - current = currentPrimaryChildFragment.sibling; - var primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment + 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 & 8 && + workInProgress.mode & 4 && ((primaryChildren.actualDuration = 0), (primaryChildren.actualStartTime = -1), - (primaryChildren.selfBaseDuration = - currentPrimaryChildFragment.selfBaseDuration), - (primaryChildren.treeBaseDuration = - currentPrimaryChildFragment.treeBaseDuration)), - (currentPrimaryChildFragment = primaryChildren.lastEffect), - null !== currentPrimaryChildFragment - ? ((workInProgress.firstEffect = primaryChildren.firstEffect), - (workInProgress.lastEffect = currentPrimaryChildFragment), - (currentPrimaryChildFragment.nextEffect = null)) - : (workInProgress.firstEffect = workInProgress.lastEffect = null)) - : (primaryChildren = createWorkInProgress( - currentPrimaryChildFragment, - primaryChildProps - )); - null !== current - ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) + (primaryChildren.selfBaseDuration = current.selfBaseDuration), + (primaryChildren.treeBaseDuration = current.treeBaseDuration)), + (workInProgress.deletions = null)) + : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), + (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); + null !== currentFallbackChildFragment + ? (fallbackChildren = createWorkInProgress( + currentFallbackChildFragment, + fallbackChildren + )) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4703,8 +4798,7 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode, - lastEffectBeforeRendering + tailMode ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4714,16 +4808,14 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode, - lastEffect: lastEffectBeforeRendering + tailMode: tailMode }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode), - (renderState.lastEffect = lastEffectBeforeRendering)); + (renderState.tailMode = tailMode)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4732,9 +4824,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); else { - if (null !== current && 0 !== (current.flags & 64)) + if (null !== current && 0 !== (current.flags & 128)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4757,7 +4849,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4778,8 +4870,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "backwards": @@ -4801,19 +4892,11 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode, - workInProgress.lastEffect + tailMode ); break; case "together": - initSuspenseListRenderState( - workInProgress, - !1, - null, - null, - void 0, - workInProgress.lastEffect - ); + initSuspenseListRenderState(workInProgress, !1, null, null, void 0); break; default: workInProgress.memoizedState = null; @@ -4824,25 +4907,23 @@ function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); profilerStartTime = -1; workInProgressRootSkippedLanes |= workInProgress.lanes; - if (0 !== (renderLanes & workInProgress.childLanes)) { - 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; + 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 null; + return workInProgress.child; } var appendAllChildren, updateHostContainer, @@ -4889,16 +4970,76 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$65 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), + for (var lastTailNode$63 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$65 + null === lastTailNode$63 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$65.sibling = null); + : (lastTailNode$63.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 & 4)) { + for ( + var treeBaseDuration$65 = completedWork.selfBaseDuration, + child$66 = completedWork.child; + null !== child$66; + + ) + (newChildLanes |= child$66.lanes | child$66.childLanes), + (subtreeFlags |= child$66.subtreeFlags & 131072), + (subtreeFlags |= child$66.flags & 131072), + (treeBaseDuration$65 += child$66.treeBaseDuration), + (child$66 = child$66.sibling); + completedWork.treeBaseDuration = treeBaseDuration$65; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 131072), + (subtreeFlags |= treeBaseDuration$65.flags & 131072), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + else if (0 !== (completedWork.mode & 4)) { + treeBaseDuration$65 = completedWork.actualDuration; + child$66 = completedWork.selfBaseDuration; + for (var child = completedWork.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (subtreeFlags |= child.subtreeFlags), + (subtreeFlags |= child.flags), + (treeBaseDuration$65 += child.actualDuration), + (child$66 += child.treeBaseDuration), + (child = child.sibling); + completedWork.actualDuration = treeBaseDuration$65; + completedWork.treeBaseDuration = child$66; + } else + for ( + treeBaseDuration$65 = completedWork.child; + null !== treeBaseDuration$65; + + ) + (newChildLanes |= + treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), + (subtreeFlags |= treeBaseDuration$65.subtreeFlags), + (subtreeFlags |= treeBaseDuration$65.flags), + (treeBaseDuration$65.return = completedWork), + (treeBaseDuration$65 = treeBaseDuration$65.sibling); + completedWork.subtreeFlags |= subtreeFlags; + completedWork.childLanes = newChildLanes; + return didBailout; +} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4912,76 +5053,80 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return null; + return bubbleProperties(workInProgress), null; case 1: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 3: return ( + (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), - (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 256), - updateHostContainer(workInProgress), + (workInProgress.flags |= 512), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), null ); case 5: popHostContext(workInProgress); - var rootContainerInstance = requiredContext( - rootInstanceStackCursor.current - ); - renderLanes = workInProgress.type; + renderLanes = requiredContext(rootInstanceStackCursor.current); + var type = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - renderLanes, + type, newProps, - rootContainerInstance + renderLanes ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 128); + 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(); - renderLanes = getViewConfigForType(renderLanes); + type = getViewConfigForType(type); var updatePayload = diffProperties( null, emptyObject, newProps, - renderLanes.validAttributes + type.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - renderLanes.uiViewClassName, - rootContainerInstance, + type.uiViewClassName, + renderLanes, updatePayload ); - rootContainerInstance = new ReactNativeFiberHostComponent( + renderLanes = new ReactNativeFiberHostComponent( current, - renderLanes, + type, workInProgress ); instanceCache.set(current, workInProgress); instanceProps.set(current, newProps); - appendAllChildren(rootContainerInstance, workInProgress, !1, !1); - workInProgress.stateNode = rootContainerInstance; - finalizeInitialChildren(rootContainerInstance) && - (workInProgress.flags |= 4); - null !== workInProgress.ref && (workInProgress.flags |= 128); + 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) @@ -5001,32 +5146,32 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - rootContainerInstance = allocateTag(); + renderLanes = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - rootContainerInstance, + renderLanes, "RCTRawText", current, { text: newProps } ); - instanceCache.set(rootContainerInstance, workInProgress); - workInProgress.stateNode = rootContainerInstance; + instanceCache.set(renderLanes, workInProgress); + workInProgress.stateNode = renderLanes; } + bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 64)) + if (0 !== (workInProgress.flags & 128)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 8) && + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - rootContainerInstance = !1; - null !== current && - (rootContainerInstance = null !== current.memoizedState); - if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) + renderLanes = !1; + null !== current && (renderLanes = null !== current.memoizedState); + if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5041,89 +5186,100 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 134217727) && - 0 === (workInProgressRootUpdatedLanes & 134217727)) || + (0 === (workInProgressRootSkippedLanes & 268435455) && + 0 === (workInProgressRootUpdatedLanes & 268435455)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || rootContainerInstance) workInProgress.flags |= 4; + if (newProps || renderLanes) workInProgress.flags |= 4; + bubbleProperties(workInProgress); + 0 !== (workInProgress.mode & 4) && + newProps && + ((current = workInProgress.child), + null !== current && + (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return popHostContainer(), updateHostContainer(workInProgress), null; + return ( + popHostContainer(), + updateHostContainer(current, workInProgress), + bubbleProperties(workInProgress), + null + ); case 10: - return popProvider(workInProgress), null; + return ( + popProvider(workInProgress.type._context), + bubbleProperties(workInProgress), + null + ); case 17: - return isContextProvider(workInProgress.type) && popContext(), null; + return ( + isContextProvider(workInProgress.type) && popContext(), + bubbleProperties(workInProgress), + null + ); case 19: pop(suspenseStackCursor); - newProps = workInProgress.memoizedState; - if (null === newProps) return null; - rootContainerInstance = 0 !== (workInProgress.flags & 64); - updatePayload = newProps.rendering; + type = workInProgress.memoizedState; + if (null === type) return bubbleProperties(workInProgress), null; + newProps = 0 !== (workInProgress.flags & 128); + updatePayload = type.rendering; if (null === updatePayload) - if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); + if (newProps) cutOffTailIfNeeded(type, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 64)) + (null !== current && 0 !== (current.flags & 128)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 64; - cutOffTailIfNeeded(newProps, !1); + workInProgress.flags |= 128; + cutOffTailIfNeeded(type, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - null === newProps.lastEffect && - (workInProgress.firstEffect = null); - workInProgress.lastEffect = newProps.lastEffect; + workInProgress.subtreeFlags = 0; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (rootContainerInstance = newProps), + (renderLanes = newProps), (updatePayload = current), - (rootContainerInstance.flags &= 2), - (rootContainerInstance.nextEffect = null), - (rootContainerInstance.firstEffect = null), - (rootContainerInstance.lastEffect = null), - (renderLanes = rootContainerInstance.alternate), - null === renderLanes - ? ((rootContainerInstance.childLanes = 0), - (rootContainerInstance.lanes = updatePayload), - (rootContainerInstance.child = null), - (rootContainerInstance.memoizedProps = null), - (rootContainerInstance.memoizedState = null), - (rootContainerInstance.updateQueue = null), - (rootContainerInstance.dependencies = null), - (rootContainerInstance.stateNode = null), - (rootContainerInstance.selfBaseDuration = 0), - (rootContainerInstance.treeBaseDuration = 0)) - : ((rootContainerInstance.childLanes = - renderLanes.childLanes), - (rootContainerInstance.lanes = renderLanes.lanes), - (rootContainerInstance.child = renderLanes.child), - (rootContainerInstance.memoizedProps = - renderLanes.memoizedProps), - (rootContainerInstance.memoizedState = - renderLanes.memoizedState), - (rootContainerInstance.updateQueue = - renderLanes.updateQueue), - (rootContainerInstance.type = renderLanes.type), - (updatePayload = renderLanes.dependencies), - (rootContainerInstance.dependencies = + (renderLanes.flags &= 131074), + (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 = type.subtreeFlags), + (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 }), - (rootContainerInstance.selfBaseDuration = - renderLanes.selfBaseDuration), - (rootContainerInstance.treeBaseDuration = - renderLanes.treeBaseDuration)), + (renderLanes.selfBaseDuration = type.selfBaseDuration), + (renderLanes.treeBaseDuration = type.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5133,80 +5289,76 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== newProps.tail && + null !== type.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); } else { - if (!rootContainerInstance) + if (!newProps) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), + ((workInProgress.flags |= 128), + (newProps = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(newProps, !0), - null === newProps.tail && - "hidden" === newProps.tailMode && + cutOffTailIfNeeded(type, !0), + null === type.tail && + "hidden" === type.tailMode && !updatePayload.alternate) ) - return ( - (workInProgress = workInProgress.lastEffect = - newProps.lastEffect), - null !== workInProgress && (workInProgress.nextEffect = null), - null - ); + return bubbleProperties(workInProgress), null; } else - 2 * now() - newProps.renderingStartTime > + 2 * now() - type.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 64), - (rootContainerInstance = !0), - cutOffTailIfNeeded(newProps, !1), - (workInProgress.lanes = 33554432), - markSpawnedWork(33554432)); - newProps.isBackwards + ((workInProgress.flags |= 128), + (newProps = !0), + cutOffTailIfNeeded(type, !1), + (workInProgress.lanes = 8388608), + markSpawnedWork(8388608)); + type.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = newProps.last), + : ((current = type.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (newProps.last = updatePayload)); + (type.last = updatePayload)); } - return null !== newProps.tail - ? ((current = newProps.tail), - (newProps.rendering = current), - (newProps.tail = current.sibling), - (newProps.lastEffect = workInProgress.lastEffect), - (newProps.renderingStartTime = now()), - (current.sibling = null), - (workInProgress = suspenseStackCursor.current), - push( - suspenseStackCursor, - rootContainerInstance - ? (workInProgress & 1) | 2 - : workInProgress & 1 - ), - current) - : null; + 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) !== - (null !== workInProgress.memoizedState) && + (null !== current.memoizedState) !== renderLanes && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), + (renderLanes && + 0 === (subtreeRenderLanes & 1073741824) && + 0 !== (workInProgress.mode & 2)) || + bubbleProperties(workInProgress), null ); } @@ -5221,9 +5373,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + return flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5233,11 +5385,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 64)) + if (0 !== (flags & 128)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -8193) | 64; + workInProgress.flags = (flags & -16385) | 128; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5245,9 +5397,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 8192 - ? ((workInProgress.flags = (flags & -8193) | 64), - 0 !== (workInProgress.mode & 8) && + flags & 16384 + ? ((workInProgress.flags = (flags & -16385) | 128), + 0 !== (workInProgress.mode & 4) && transferActualDuration(workInProgress), workInProgress) : null @@ -5257,10 +5409,12 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress), null; + return popProvider(workInProgress.type._context), null; case 22: case 23: return popRenderLanes(), null; + case 24: + return null; default: return null; } @@ -5333,152 +5487,150 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; -function safelyDetachRef(current) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, + nextEffect = null; +function safelyDetachRef(current, nearestMountedAncestor) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, refError); + captureCommitPhaseError(current, nearestMountedAncestor, refError); } else ref.current = null; } -function commitBeforeMutationLifeCycles(current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - return; - case 1: - if (finishedWork.flags & 256 && null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState; - current = finishedWork.stateNode; - finishedWork = current.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); - current.__reactInternalSnapshotBeforeUpdate = finishedWork; +var focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; +function commitBeforeMutationEffects(root, firstChild) { + focusedInstanceHandle = null; + for (nextEffect = firstChild; null !== nextEffect; ) { + root = nextEffect; + firstChild = root.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) + doesFiberContain(firstChild[i], focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + firstChild = root.child; + if (0 !== (root.subtreeFlags & 516) && null !== firstChild) + (firstChild.return = root), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + root = nextEffect; + try { + var current = root.alternate, + flags = root.flags; + if ( + !shouldFireAfterActiveInstanceBlur && + null !== focusedInstanceHandle + ) { + var JSCompiler_temp; + if ((JSCompiler_temp = 13 === root.tag)) + a: { + if (null !== current) { + var oldState = current.memoizedState; + if (null === oldState || null !== oldState.dehydrated) { + var newState = root.memoizedState; + JSCompiler_temp = + null !== newState && null === newState.dehydrated; + break a; + } + } + JSCompiler_temp = !1; + } + JSCompiler_temp && + doesFiberContain(root, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0); + } + if (0 !== (flags & 512)) + switch (root.tag) { + case 0: + case 11: + case 15: + break; + case 1: + if (null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState, + instance = root.stateNode, + snapshot = instance.getSnapshotBeforeUpdate( + root.elementType === root.type + ? prevProps + : resolveDefaultProps(root.type, prevProps), + prevState + ); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + break; + case 3: + break; + case 5: + case 6: + case 4: + case 17: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + } catch (error) { + captureCommitPhaseError(root, root.return, error); + } + firstChild = root.sibling; + if (null !== firstChild) { + firstChild.return = root.return; + nextEffect = firstChild; + break; + } + nextEffect = root.return; } - return; - case 3: - return; - case 5: - case 6: - case 4: - case 17: - return; } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + current = shouldFireAfterActiveInstanceBlur; + shouldFireAfterActiveInstanceBlur = !1; + focusedInstanceHandle = null; + return current; } -function commitLifeCycles(finishedRoot, current, finishedWork) { - switch (finishedWork.tag) { - case 0: - case 11: - case 15: - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - if (3 === (finishedRoot.tag & 3)) { - var create$82 = finishedRoot.create; - finishedRoot.destroy = create$82(); +function commitHookEffectListUnmount( + flags, + finishedWork, + nearestMountedAncestor$jscomp$0 +) { + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do { + if ((effect.tag & flags) === flags) { + var destroy = effect.destroy; + effect.destroy = void 0; + if (void 0 !== destroy) { + var current = finishedWork, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(current, nearestMountedAncestor, error); } - finishedRoot = finishedRoot.next; - } while (finishedRoot !== current); - } - current = finishedWork.updateQueue; - current = null !== current ? current.lastEffect : null; - if (null !== current) { - finishedRoot = current = current.next; - do { - var _effect = finishedRoot; - create$82 = _effect.next; - _effect = _effect.tag; - 0 !== (_effect & 4) && - 0 !== (_effect & 1) && - (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), - enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); - finishedRoot = create$82; - } while (finishedRoot !== current); + } } - return; - case 1: - finishedRoot = finishedWork.stateNode; - finishedWork.flags & 4 && - (null === current - ? finishedRoot.componentDidMount() - : ((create$82 = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps( - finishedWork.type, - current.memoizedProps - )), - finishedRoot.componentDidUpdate( - create$82, - current.memoizedState, - finishedRoot.__reactInternalSnapshotBeforeUpdate - ))); - current = finishedWork.updateQueue; - null !== current && - commitUpdateQueue(finishedWork, current, finishedRoot); - return; - case 3: - current = finishedWork.updateQueue; - if (null !== current) { - finishedRoot = null; - if (null !== finishedWork.child) - switch (finishedWork.child.tag) { - case 5: - finishedRoot = finishedWork.child.stateNode; - break; - case 1: - finishedRoot = finishedWork.child.stateNode; - } - commitUpdateQueue(finishedWork, current, finishedRoot); + effect = effect.next; + } while (effect !== updateQueue); + } +} +function commitHookEffectListMount(tag, finishedWork) { + finishedWork = finishedWork.updateQueue; + finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; + if (null !== finishedWork) { + var effect = (finishedWork = finishedWork.next); + do { + if ((effect.tag & tag) === tag) { + var create$84 = effect.create; + effect.destroy = create$84(); } - return; - case 5: - return; - case 6: - return; - case 4: - return; - case 12: - create$82 = finishedWork.memoizedProps.onRender; - _effect = commitTime; - "function" === typeof create$82 && - create$82( - finishedWork.memoizedProps.id, - null === current ? "mount" : "update", - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - _effect, - finishedRoot.memoizedInteractions - ); - return; - case 13: - return; - case 19: - case 17: - case 20: - case 21: - case 22: - case 23: - return; + effect = effect.next; + } while (effect !== finishedWork); } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5538,7 +5690,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current) { +function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5555,26 +5707,24 @@ function commitUnmount(finishedRoot, current) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect2 = effect, - destroy = _effect2.destroy; - _effect2 = _effect2.tag; - if (void 0 !== destroy) - if (0 !== (_effect2 & 4)) - enqueuePendingPassiveHookEffectUnmount(current, effect); - else { - _effect2 = current; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect2, error); - } + var _effect = effect, + destroy = _effect.destroy; + _effect = _effect.tag; + if (void 0 !== destroy && 0 !== (_effect & 2)) { + _effect = current; + var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect, nearestMountedAncestor, error); } + } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5582,26 +5732,34 @@ function commitUnmount(finishedRoot, current) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError(current, unmountError); + captureCommitPhaseError( + current, + nearestMountedAncestor$jscomp$0, + unmountError + ); } break; case 5: - safelyDetachRef(current); + safelyDetachRef(current, nearestMountedAncestor$jscomp$0); break; case 4: - unmountHostComponents(finishedRoot, current); + unmountHostComponents( + finishedRoot, + current, + nearestMountedAncestor$jscomp$0 + ); } } -function detachFiberMutation(fiber) { +function detachFiberAfterEffects(fiber) { fiber.alternate = null; fiber.child = null; + fiber.deletions = null; fiber.dependencies = null; - fiber.firstEffect = null; - fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.return = null; + fiber.sibling = null; + fiber.stateNode = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5636,7 +5794,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 16 && (parentFiber.flags &= -17); + parentFiber.flags & 32 && (parentFiber.flags &= -33); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5752,7 +5910,11 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents(finishedRoot$jscomp$0, current) { +function unmountHostComponents( + finishedRoot$jscomp$0, + current, + nearestMountedAncestor$jscomp$0 +) { for ( var node = current, currentParentIsValid = !1, @@ -5790,12 +5952,13 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, + nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0), + (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5822,18 +5985,18 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { [0] )) : ((finishedRoot = currentParent), - (node$jscomp$0 = node.stateNode), - recursivelyUncacheFiberNode(node$jscomp$0), + (nearestMountedAncestor = node.stateNode), + recursivelyUncacheFiberNode(nearestMountedAncestor), (root = finishedRoot._children), - (node$jscomp$0 = root.indexOf(node$jscomp$0)), - root.splice(node$jscomp$0, 1), + (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), + root.splice(nearestMountedAncestor, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [node$jscomp$0] + [nearestMountedAncestor] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5844,7 +6007,12 @@ function unmountHostComponents(finishedRoot$jscomp$0, current) { continue; } } else if ( - (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) + (commitUnmount( + finishedRoot$jscomp$0, + node, + nearestMountedAncestor$jscomp$0 + ), + null !== node.child) ) { node.child.return = node; node = node.child; @@ -5866,42 +6034,31 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do - 3 === (effect.tag & 3) && - ((finishedWork = effect.destroy), - (effect.destroy = void 0), - void 0 !== finishedWork && finishedWork()), - (effect = effect.next); - while (effect !== updateQueue); - } + commitHookEffectListUnmount(3, finishedWork, finishedWork.return); return; case 1: return; case 5: - updateQueue = finishedWork.stateNode; - if (null != updateQueue) { - effect = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : effect; + var instance = finishedWork.stateNode; + if (null != instance) { + var newProps = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : newProps; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = updateQueue.viewConfig), - instanceProps.set(updateQueue._nativeTag, effect), - (effect = diffProperties( + ((finishedWork = instance.viewConfig), + instanceProps.set(instance._nativeTag, newProps), + (newProps = diffProperties( null, current, - effect, + newProps, finishedWork.validAttributes )), - null != effect && + null != newProps && ReactNativePrivateInterface.UIManager.updateView( - updateQueue._nativeTag, + instance._nativeTag, finishedWork.uiViewClassName, - effect + newProps )); } return; @@ -5960,13 +6117,210 @@ function attachSuspenseRetryListeners(finishedWork) { }); } } -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - return null !== current && - ((current = current.memoizedState), - null === current || null !== current.dehydrated) - ? ((finishedWork = finishedWork.memoizedState), - null !== finishedWork && null === finishedWork.dehydrated) - : !1; +function commitMutationEffects(root, renderPriorityLevel, firstChild) { + for (nextEffect = firstChild; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + firstChild = renderPriorityLevel.deletions; + if (null !== firstChild) + for (var i = 0; i < firstChild.length; i++) { + var childToDelete = firstChild[i]; + try { + unmountHostComponents(root, childToDelete, renderPriorityLevel); + var alternate = childToDelete.alternate; + childToDelete.return = null; + null !== alternate && (alternate.return = null); + } catch (error) { + captureCommitPhaseError(childToDelete, renderPriorityLevel, error); + } + } + firstChild = renderPriorityLevel.child; + if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) + (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); + else + for (; null !== nextEffect; ) { + renderPriorityLevel = nextEffect; + try { + var flags = renderPriorityLevel.flags; + if (flags & 256) { + var current = renderPriorityLevel.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 2054) { + case 2: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + break; + case 6: + commitPlacement(renderPriorityLevel); + renderPriorityLevel.flags &= -3; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 2048: + renderPriorityLevel.flags &= -2049; + break; + case 2052: + renderPriorityLevel.flags &= -2049; + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + break; + case 4: + commitWork(renderPriorityLevel.alternate, renderPriorityLevel); + } + } catch (error) { + captureCommitPhaseError( + renderPriorityLevel, + renderPriorityLevel.return, + error + ); + } + firstChild = renderPriorityLevel.sibling; + if (null !== firstChild) { + firstChild.return = renderPriorityLevel.return; + nextEffect = firstChild; + break; + } + nextEffect = renderPriorityLevel.return; + } + } +} +function commitLayoutEffects(finishedWork, root) { + for (nextEffect = finishedWork; null !== nextEffect; ) { + var fiber = nextEffect, + firstChild = fiber.child; + if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) + (firstChild.return = fiber), (nextEffect = firstChild); + else + for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + if (0 !== (fiber$jscomp$0.flags & 324)) { + var current = fiber$jscomp$0.alternate; + try { + var finishedRoot = firstChild; + if (0 !== (fiber$jscomp$0.flags & 68)) + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(3, fiber$jscomp$0); + break; + case 1: + var instance = fiber$jscomp$0.stateNode; + if (fiber$jscomp$0.flags & 4) + if (null === current) instance.componentDidMount(); + else { + var prevProps = + fiber$jscomp$0.elementType === fiber$jscomp$0.type + ? current.memoizedProps + : resolveDefaultProps( + fiber$jscomp$0.type, + current.memoizedProps + ); + instance.componentDidUpdate( + prevProps, + current.memoizedState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + var updateQueue = fiber$jscomp$0.updateQueue; + null !== updateQueue && + commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); + break; + case 3: + var updateQueue$85 = fiber$jscomp$0.updateQueue; + if (null !== updateQueue$85) { + finishedRoot = null; + if (null !== fiber$jscomp$0.child) + switch (fiber$jscomp$0.child.tag) { + case 5: + finishedRoot = fiber$jscomp$0.child.stateNode; + break; + case 1: + finishedRoot = fiber$jscomp$0.child.stateNode; + } + commitUpdateQueue( + fiber$jscomp$0, + updateQueue$85, + finishedRoot + ); + } + break; + case 5: + break; + case 6: + break; + case 4: + break; + case 12: + var onRender = fiber$jscomp$0.memoizedProps.onRender, + commitTime$88 = commitTime; + current = null === current ? "mount" : "update"; + "function" === typeof onRender && + onRender( + fiber$jscomp$0.memoizedProps.id, + current, + fiber$jscomp$0.actualDuration, + fiber$jscomp$0.treeBaseDuration, + fiber$jscomp$0.actualStartTime, + commitTime$88, + finishedRoot.memoizedInteractions + ); + break; + case 13: + break; + case 19: + case 17: + case 21: + case 22: + case 23: + break; + default: + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } + if (fiber$jscomp$0.flags & 256) { + finishedRoot = void 0; + var ref = fiber$jscomp$0.ref; + if (null !== ref) { + var instance$jscomp$0 = fiber$jscomp$0.stateNode; + switch (fiber$jscomp$0.tag) { + case 5: + finishedRoot = instance$jscomp$0; + break; + default: + finishedRoot = instance$jscomp$0; + } + "function" === typeof ref + ? ref(finishedRoot) + : (ref.current = finishedRoot); + } + } + } catch (error) { + captureCommitPhaseError( + fiber$jscomp$0, + fiber$jscomp$0.return, + error + ); + } + } + if (fiber$jscomp$0 === fiber) { + nextEffect = null; + break; + } + finishedRoot = fiber$jscomp$0.sibling; + if (null !== finishedRoot) { + finishedRoot.return = fiber$jscomp$0.return; + nextEffect = finishedRoot; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -5979,14 +6333,11 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, - workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, - mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, - nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -5994,17 +6345,12 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, - pendingPassiveHookEffectsMount = [], - pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventWipLanes = 0, - currentEventPendingLanes = 0, - focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; + currentEventTransitionLane = 0; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6014,30 +6360,22 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 2)) return 1; - if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - 0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes); - if (0 !== ReactCurrentBatchConfig.transition) { - 0 !== currentEventPendingLanes && - (currentEventPendingLanes = - null !== mostRecentlyUpdatedRoot - ? mostRecentlyUpdatedRoot.pendingLanes - : 0); - fiber = currentEventWipLanes; - var lane = 4186112 & ~currentEventPendingLanes; - lane &= -lane; - 0 === lane && - ((fiber = 4186112 & ~fiber), - (lane = fiber & -fiber), - 0 === lane && (lane = 8192)); - return lane; - } + if (0 === (fiber & 1)) return 1; + if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + if (0 !== ReactCurrentBatchConfig.transition) + return ( + 0 === currentEventTransitionLane && + ((fiber = nextTransitionLane), + (nextTransitionLane <<= 1), + 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), + (currentEventTransitionLane = fiber)), + currentEventTransitionLane + ); fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12, currentEventWipLanes)) + ? (fiber = findUpdateLane(12)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber, currentEventWipLanes))); + (fiber = findUpdateLane(fiber))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6070,7 +6408,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - mostRecentlyUpdatedRoot = fiber; + return fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6095,15 +6433,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$7 = 31 - clz32(lanes), - lane = 1 << index$7, - expirationTime = expirationTimes[index$7]; + var index$6 = 31 - clz32(lanes), + lane = 1 << index$6, + expirationTime = expirationTimes[index$6]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$7] = + expirationTimes[index$6] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6118,45 +6456,42 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - if (0 === suspendedLanes) - null !== existingCallbackNode && - (existingCallbackNode !== fakeCallbackNode && + 0 === suspendedLanes + ? (null !== existingCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)); - else { - if (null !== existingCallbackNode) { - if (root.callbackPriority === currentTime) return; - existingCallbackNode !== fakeCallbackNode && - Scheduler_cancelCallback(existingCallbackNode); - } - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = fakeCallbackNode)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))); - root.callbackPriority = currentTime; - root.callbackNode = existingCallbackNode; - } -} -function performConcurrentWorkOnRoot(root) { + (root.callbackPriority = 0)) + : root.callbackPriority !== currentTime && + (null != existingCallbackNode && + Scheduler_cancelCallback(existingCallbackNode), + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = null)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority( + currentTime + )), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))), + (root.callbackPriority = currentTime), + (root.callbackNode = existingCallbackNode)); +} +function performConcurrentWorkOnRoot(root, didTimeout) { currentEventTime = -1; - currentEventPendingLanes = currentEventWipLanes = 0; + currentEventTransitionLane = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6167,8 +6502,14 @@ function performConcurrentWorkOnRoot(root) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; + if (didTimeout) + return ( + (root.expiredLanes |= lanes & root.pendingLanes), + ensureRootIsScheduled(root, now()), + null + ); var lanes$jscomp$0 = lanes; - var exitStatus = executionContext; + didTimeout = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -6190,21 +6531,19 @@ function performConcurrentWorkOnRoot(root) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = exitStatus; + executionContext = didTimeout; null !== workInProgress - ? (exitStatus = 0) + ? (didTimeout = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (exitStatus = workInProgressRootExitStatus)); - if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) - prepareFreshStack(root, 0); - else if (0 !== exitStatus) { - 2 === exitStatus && + (didTimeout = workInProgressRootExitStatus)); + if (0 !== didTimeout) { + 2 === didTimeout && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); - if (1 === exitStatus) + 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); + if (1 === didTimeout) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6212,7 +6551,7 @@ function performConcurrentWorkOnRoot(root) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (exitStatus) { + switch (didTimeout) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6222,9 +6561,9 @@ function performConcurrentWorkOnRoot(root) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 62914560) === lanes && - ((exitStatus = globalMostRecentFallbackTime + 500 - now()), - 10 < exitStatus) + (lanes & 125829120) === lanes && + ((didTimeout = globalMostRecentFallbackTime + 500 - now()), + 10 < didTimeout) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -6235,7 +6574,7 @@ function performConcurrentWorkOnRoot(root) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - exitStatus + didTimeout ); break; } @@ -6243,13 +6582,13 @@ function performConcurrentWorkOnRoot(root) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 4186112) === lanes) break; - exitStatus = root.eventTimes; + if ((lanes & 8388096) === lanes) break; + didTimeout = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { - var index$6 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$6; - index$6 = exitStatus[index$6]; - index$6 > prevDispatcher && (prevDispatcher = index$6); + var index$5 = 31 - clz32(lanes); + lanes$jscomp$0 = 1 << index$5; + index$5 = didTimeout[index$5]; + index$5 > prevDispatcher && (prevDispatcher = index$5); lanes &= ~lanes$jscomp$0; } lanes = prevDispatcher; @@ -6295,9 +6634,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$11 = 31 - clz32(suspendedLanes), - lane = 1 << index$11; - root[index$11] = -1; + var index$7 = 31 - clz32(suspendedLanes), + lane = 1 << index$7; + root[index$7] = -1; suspendedLanes &= ~lane; } } @@ -6305,17 +6644,12 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - if ( + var lanes = root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ) { - var lanes = workInProgressRootRenderLanes; - var exitStatus = renderRootSync(root, lanes); - 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && - ((lanes = getNextLanes(root, lanes)), - (exitStatus = renderRootSync(root, lanes))); - } else - (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); + ? workInProgressRootRenderLanes + : getNextLanes(root, 0); + var exitStatus = renderRootSync(root, lanes); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6334,11 +6668,6 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } -function pushRenderLanes(fiber, lanes) { - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= lanes; - workInProgressRootIncludedLanes |= lanes; -} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6378,7 +6707,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork); + popProvider(interruptedWork.type._context); break; case 22: case 23: @@ -6388,10 +6717,29 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; + if (null !== interleavedQueues) { + for (root = 0; root < interleavedQueues.length; root++) + if ( + ((lanes = interleavedQueues[root]), + (timeoutHandle = lanes.interleaved), + null !== timeoutHandle) + ) { + lanes.interleaved = null; + interruptedWork = timeoutHandle.next; + var lastPendingUpdate = lanes.pending; + if (null !== lastPendingUpdate) { + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = interruptedWork; + timeoutHandle.next = firstPendingUpdate; + } + lanes.pending = timeoutHandle; + } + interleavedQueues = null; + } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6422,7 +6770,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 8 && + erroredWork.mode & 4 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6430,15 +6778,18 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 4096; - sourceFiber.firstEffect = sourceFiber.lastEffect = null; + sourceFiber.flags |= 8192; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value; - if (0 === (sourceFiber.mode & 2)) { + var wakeable = value, + tag = sourceFiber.tag; + if ( + 0 === (sourceFiber.mode & 1) && + (0 === tag || 11 === tag || 15 === tag) + ) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6449,15 +6800,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { - var nextState = workInProgress$77.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { + var nextState = workInProgress$79.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$77.memoizedProps; + var props = workInProgress$79.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6469,16 +6820,19 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$77.updateQueue; + var wakeables = workInProgress$79.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$77.updateQueue = updateQueue; + workInProgress$79.updateQueue = updateQueue; } else wakeables.add(wakeable); - if (0 === (workInProgress$77.mode & 2)) { - workInProgress$77.flags |= 64; - sourceFiber.flags |= 32768; - sourceFiber.flags &= -5029; + if ( + 0 === (workInProgress$79.mode & 1) && + workInProgress$79 !== returnFiber + ) { + workInProgress$79.flags |= 128; + sourceFiber.flags |= 65536; + sourceFiber.flags &= -10053; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6509,12 +6863,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$77.flags |= 8192; - workInProgress$77.lanes = thrownValue; + workInProgress$79.flags |= 16384; + workInProgress$79.lanes = thrownValue; break a; } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6523,47 +6877,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$77 = returnFiber; + workInProgress$79 = returnFiber; do { - switch (workInProgress$77.tag) { + switch (workInProgress$79.tag) { case 3: root = value; - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$78 = createRootErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$80 = createRootErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$78); + enqueueCapturedUpdate(workInProgress$79, update$80); break a; case 1: root = value; - var ctor = workInProgress$77.type, - instance = workInProgress$77.stateNode; + var ctor = workInProgress$79.type, + instance = workInProgress$79.stateNode; if ( - 0 === (workInProgress$77.flags & 64) && + 0 === (workInProgress$79.flags & 128) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$77.flags |= 8192; + workInProgress$79.flags |= 16384; thrownValue &= -thrownValue; - workInProgress$77.lanes |= thrownValue; - var update$81 = createClassErrorUpdate( - workInProgress$77, + workInProgress$79.lanes |= thrownValue; + var update$83 = createClassErrorUpdate( + workInProgress$79, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$77, update$81); + enqueueCapturedUpdate(workInProgress$79, update$83); break a; } } - workInProgress$77 = workInProgress$77.return; - } while (null !== workInProgress$77); + workInProgress$79 = workInProgress$79.return; + } while (null !== workInProgress$79); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6622,7 +6976,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 8) + 0 !== (unitOfWork.mode & 4) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6639,8 +6993,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 4096)) { - if (0 === (completedWork.mode & 8)) + if (0 === (completedWork.flags & 8192)) { + if (0 === (completedWork.mode & 4)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6653,65 +7007,14 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } - current = completedWork; - if ( - (23 !== current.tag && 22 !== current.tag) || - null === current.memoizedState || - 0 !== (subtreeRenderLanes & 1073741824) || - 0 === (current.mode & 4) - ) { - fiber = 0; - if (0 !== (current.mode & 8)) { - for ( - var actualDuration = current.actualDuration, - treeBaseDuration = current.selfBaseDuration, - shouldBubbleActualDurations = - null === current.alternate || - current.child !== current.alternate.child, - child = current.child; - null !== child; - - ) - (fiber |= child.lanes | child.childLanes), - shouldBubbleActualDurations && - (actualDuration += child.actualDuration), - (treeBaseDuration += child.treeBaseDuration), - (child = child.sibling); - 13 === current.tag && - null !== current.memoizedState && - ((shouldBubbleActualDurations = current.child), - null !== shouldBubbleActualDurations && - (treeBaseDuration -= - shouldBubbleActualDurations.treeBaseDuration)); - current.actualDuration = actualDuration; - current.treeBaseDuration = treeBaseDuration; - } else - for (actualDuration = current.child; null !== actualDuration; ) - (fiber |= actualDuration.lanes | actualDuration.childLanes), - (actualDuration = actualDuration.sibling); - current.childLanes = fiber; - } - null !== unitOfWork && - 0 === (unitOfWork.flags & 4096) && - (null === unitOfWork.firstEffect && - (unitOfWork.firstEffect = completedWork.firstEffect), - null !== completedWork.lastEffect && - (null !== unitOfWork.lastEffect && - (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), - (unitOfWork.lastEffect = completedWork.lastEffect)), - 1 < completedWork.flags && - (null !== unitOfWork.lastEffect - ? (unitOfWork.lastEffect.nextEffect = completedWork) - : (unitOfWork.firstEffect = completedWork), - (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 4095; + current.flags &= 8191; workInProgress = current; return; } - if (0 !== (completedWork.mode & 8)) { + if (0 !== (completedWork.mode & 4)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6719,8 +7022,9 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), - (unitOfWork.flags |= 4096)); + ((unitOfWork.flags |= 8192), + (unitOfWork.subtreeFlags = 0), + (unitOfWork.deletions = null)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6751,190 +7055,65 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes, - remainingLanes$jscomp$0 = remainingLanes, - noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; - root.pendingLanes = remainingLanes$jscomp$0; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes$jscomp$0; - root.mutableReadLanes &= remainingLanes$jscomp$0; - root.entangledLanes &= remainingLanes$jscomp$0; - remainingLanes$jscomp$0 = root.entanglements; - for ( - var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; - 0 < noLongerPendingLanes; - - ) { - var index$12 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$12; - remainingLanes$jscomp$0[index$12] = 0; - eventTimes[index$12] = -1; - expirationTimes[index$12] = -1; - noLongerPendingLanes &= ~lane; - } + root.callbackPriority = 0; + var remainingLanes = finishedWork.lanes | finishedWork.childLanes; + markRootFinished(root, remainingLanes); null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 24) && + 0 === (remainingLanes & 8) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - 1 < finishedWork.flags - ? null !== finishedWork.lastEffect - ? ((finishedWork.lastEffect.nextEffect = finishedWork), - (remainingLanes = finishedWork.firstEffect)) - : (remainingLanes = finishedWork) - : (remainingLanes = finishedWork.firstEffect); - if (null !== remainingLanes) { - remainingLanes$jscomp$0 = executionContext; + (0 === (finishedWork.subtreeFlags & 1040) && + 0 === (finishedWork.flags & 1040)) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + remainingLanes = 0 !== (finishedWork.flags & 8054); + if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { + remainingLanes = executionContext; executionContext |= 32; - eventTimes = pushInteractions(root); - focusedInstanceHandle = ReactCurrentOwner$2.current = null; - shouldFireAfterActiveInstanceBlur = !1; - nextEffect = remainingLanes; - do - try { - commitBeforeMutationEffects(); - } catch (error) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - focusedInstanceHandle = null; + var prevInteractions = pushInteractions(root); + ReactCurrentOwner$2.current = null; + commitBeforeMutationEffects(root, finishedWork); commitTime = now$1(); - nextEffect = remainingLanes; - do - try { - for (expirationTimes = root; null !== nextEffect; ) { - var flags = nextEffect.flags; - if (flags & 128) { - var current = nextEffect.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 1038) { - case 2: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - break; - case 6: - commitPlacement(nextEffect); - nextEffect.flags &= -3; - commitWork(nextEffect.alternate, nextEffect); - break; - case 1024: - nextEffect.flags &= -1025; - break; - case 1028: - nextEffect.flags &= -1025; - commitWork(nextEffect.alternate, nextEffect); - break; - case 4: - commitWork(nextEffect.alternate, nextEffect); - break; - case 8: - noLongerPendingLanes = nextEffect; - unmountHostComponents(expirationTimes, noLongerPendingLanes); - var alternate = noLongerPendingLanes.alternate; - detachFiberMutation(noLongerPendingLanes); - null !== alternate && detachFiberMutation(alternate); - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$91) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$91); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); + commitMutationEffects(root, renderPriorityLevel, finishedWork); root.current = finishedWork; - nextEffect = remainingLanes; - do - try { - for (flags = root; null !== nextEffect; ) { - var flags$jscomp$0 = nextEffect.flags; - flags$jscomp$0 & 36 && - commitLifeCycles(flags, nextEffect.alternate, nextEffect); - if (flags$jscomp$0 & 128) { - current = void 0; - var ref = nextEffect.ref; - if (null !== ref) { - var instance = nextEffect.stateNode; - switch (nextEffect.tag) { - case 5: - current = instance; - break; - default: - current = instance; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - nextEffect = nextEffect.nextEffect; - } - } catch (error$92) { - if (null === nextEffect) throw Error("Should be working on an effect."); - captureCommitPhaseError(nextEffect, error$92); - nextEffect = nextEffect.nextEffect; - } - while (null !== nextEffect); - nextEffect = null; + commitLayoutEffects(finishedWork, root, lanes); requestPaint(); - tracing.__interactionsRef.current = eventTimes; - executionContext = remainingLanes$jscomp$0; + tracing.__interactionsRef.current = prevInteractions; + executionContext = remainingLanes; } else (root.current = finishedWork), (commitTime = now$1()); - if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) + if ((prevInteractions = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); - else - for (nextEffect = remainingLanes; null !== nextEffect; ) - (ref = nextEffect.nextEffect), - (nextEffect.nextEffect = null), - nextEffect.flags & 8 && - ((instance = nextEffect), - (instance.sibling = null), - (instance.stateNode = null)), - (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) - for ( - ref = spawnedWorkDuringRender, - spawnedWorkDuringRender = null, - instance = 0; - instance < ref.length; - instance++ - ) - scheduleInteractions(root, ref[instance], root.memoizedInteractions); + if (null !== spawnedWorkDuringRender) { + var expirationTimes = spawnedWorkDuringRender; + spawnedWorkDuringRender = null; + for (var i = 0; i < expirationTimes.length; i++) + scheduleInteractions( + root, + expirationTimes[i], + root.memoizedInteractions + ); + } schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - flags$jscomp$0 || finishPendingInteractions(root, lanes); - 1 === remainingLanes + prevInteractions || finishPendingInteractions(root, lanes); + 0 !== (remainingLanes & 1) ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - finishedWork = finishedWork.stateNode; - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - finishedWork, - renderPriorityLevel, - 64 === (finishedWork.current.flags & 64) - ); - } catch (err) {} + onCommitRoot(finishedWork.stateNode, renderPriorityLevel); ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6945,30 +7124,6 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } -function commitBeforeMutationEffects() { - for (; null !== nextEffect; ) { - var current = nextEffect.alternate; - shouldFireAfterActiveInstanceBlur || - null === focusedInstanceHandle || - (0 !== (nextEffect.flags & 8) - ? doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0) - : 13 === nextEffect.tag && - isSuspenseBoundaryBeingHidden(current, nextEffect) && - doesFiberContain(nextEffect, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0)); - var flags = nextEffect.flags; - 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); - 0 === (flags & 512) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - nextEffect = nextEffect.nextEffect; - } -} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6980,24 +7135,6 @@ function flushPassiveEffects() { } return !1; } -function enqueuePendingPassiveHookEffectMount(fiber, effect) { - pendingPassiveHookEffectsMount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} -function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { - pendingPassiveHookEffectsUnmount.push(effect, fiber); - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); -} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -7008,41 +7145,104 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root), - unmountEffects = pendingPassiveHookEffectsUnmount; - pendingPassiveHookEffectsUnmount = []; - for (var i = 0; i < unmountEffects.length; i += 2) { - var effect$97 = unmountEffects[i], - fiber = unmountEffects[i + 1], - destroy = effect$97.destroy; - effect$97.destroy = void 0; - if ("function" === typeof destroy) - try { - destroy(); - } catch (error) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error); + var prevInteractions = pushInteractions(root); + for (nextEffect = root.current; null !== nextEffect; ) { + var fiber = nextEffect, + child = fiber.child; + if (0 !== (nextEffect.flags & 16)) { + var deletions = fiber.deletions; + if (null !== deletions) { + for (var i = 0; i < deletions.length; i++) { + var fiberToDelete = deletions[i]; + for (nextEffect = fiberToDelete; null !== nextEffect; ) { + var fiber$jscomp$0 = nextEffect; + switch (fiber$jscomp$0.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); + } + var child$jscomp$0 = fiber$jscomp$0.child; + if (null !== child$jscomp$0) + (child$jscomp$0.return = fiber$jscomp$0), + (nextEffect = child$jscomp$0); + else + for (; null !== nextEffect; ) { + fiber$jscomp$0 = nextEffect; + if (fiber$jscomp$0 === fiberToDelete) { + nextEffect = null; + break; + } + child$jscomp$0 = fiber$jscomp$0.sibling; + if (null !== child$jscomp$0) { + child$jscomp$0.return = fiber$jscomp$0.return; + nextEffect = child$jscomp$0; + break; + } + nextEffect = fiber$jscomp$0.return; + } + } + fiber$jscomp$0 = fiberToDelete.alternate; + detachFiberAfterEffects(fiberToDelete); + null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); + } + nextEffect = fiber; } - } - unmountEffects = pendingPassiveHookEffectsMount; - pendingPassiveHookEffectsMount = []; - for (i = 0; i < unmountEffects.length; i += 2) { - effect$97 = unmountEffects[i]; - fiber = unmountEffects[i + 1]; - try { - var create$101 = effect$97.create; - effect$97.destroy = create$101(); - } catch (error$102) { - if (null === fiber) throw Error("Should be working on an effect."); - captureCommitPhaseError(fiber, error$102); } + if (0 !== (fiber.subtreeFlags & 1040) && null !== child) + (child.return = fiber), (nextEffect = child); + else + a: for (; null !== nextEffect; ) { + fiber = nextEffect; + if (0 !== (fiber.flags & 1024)) + switch (fiber.tag) { + case 0: + case 11: + case 15: + commitHookEffectListUnmount(5, fiber, fiber.return); + } + child = fiber.sibling; + if (null !== child) { + child.return = fiber.return; + nextEffect = child; + break a; + } + nextEffect = fiber.return; + } } - for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) - (create$101 = unmountEffects.nextEffect), - (unmountEffects.nextEffect = null), - unmountEffects.flags & 8 && - ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), - (unmountEffects = create$101); + for (nextEffect = fiber = root.current; null !== nextEffect; ) + if ( + ((child = nextEffect), + (deletions = child.child), + 0 !== (child.subtreeFlags & 1040) && null !== deletions) + ) + (deletions.return = child), (nextEffect = deletions); + else + a: for (child = fiber; null !== nextEffect; ) { + deletions = nextEffect; + if (0 !== (deletions.flags & 1024)) + try { + switch (deletions.tag) { + case 0: + case 11: + case 15: + commitHookEffectListMount(5, deletions); + } + } catch (error) { + captureCommitPhaseError(deletions, deletions.return, error); + } + if (deletions === child) { + nextEffect = null; + break a; + } + i = deletions.sibling; + if (null !== i) { + i.return = deletions.return; + nextEffect = i; + break a; + } + nextEffect = deletions.return; + } tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -7060,43 +7260,51 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, error) { +function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for (var fiber = sourceFiber.return; null !== fiber; ) { - if (3 === fiber.tag) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); + for ( + nearestMountedAncestor = sourceFiber.return; + null !== nearestMountedAncestor; + + ) { + if (3 === nearestMountedAncestor.tag) { + captureCommitPhaseErrorOnRoot( + nearestMountedAncestor, + sourceFiber, + error + ); break; - } else if (1 === fiber.tag) { - var instance = fiber.stateNode; + } else if (1 === nearestMountedAncestor.tag) { + var instance = nearestMountedAncestor.stateNode; if ( - "function" === typeof fiber.type.getDerivedStateFromError || + "function" === + typeof nearestMountedAncestor.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - var update = createClassErrorUpdate(fiber, sourceFiber, 1); - enqueueUpdate(fiber, update); - update = requestEventTime(); - fiber = markUpdateLaneFromFiberToRoot(fiber, 1); - if (null !== fiber) - markRootUpdated(fiber, 1, update), - ensureRootIsScheduled(fiber, update), - schedulePendingInteractions(fiber, 1); - else if ( - "function" === typeof instance.componentDidCatch && - (null === legacyErrorBoundariesThatAlreadyFailed || - !legacyErrorBoundariesThatAlreadyFailed.has(instance)) - ) - try { - instance.componentDidCatch(error, sourceFiber); - } catch (errorToIgnore) {} + sourceFiber = createClassErrorUpdate( + nearestMountedAncestor, + sourceFiber, + 1 + ); + enqueueUpdate(nearestMountedAncestor, sourceFiber); + sourceFiber = requestEventTime(); + nearestMountedAncestor = markUpdateLaneFromFiberToRoot( + nearestMountedAncestor, + 1 + ); + null !== nearestMountedAncestor && + (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), + ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), + schedulePendingInteractions(nearestMountedAncestor, 1)); break; } } - fiber = fiber.return; + nearestMountedAncestor = nearestMountedAncestor.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7108,7 +7316,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 62914560) === + (workInProgressRootRenderLanes & 125829120) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -7122,14 +7330,13 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 2) + 0 === (wakeable & 1) ? (wakeable = 1) - : 0 === (wakeable & 4) + : 0 === (wakeable & 2) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : (0 === currentEventWipLanes && - (currentEventWipLanes = workInProgressRootIncludedLanes), - (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), - 0 === wakeable && (wakeable = 4194304))); + : ((wakeable = nextRetryLane), + (nextRetryLane <<= 1), + 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -7146,85 +7353,90 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; - else if (0 !== (renderLanes & updateLanes)) - didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; else { - 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.memoizedProps.value; - var context = workInProgress.type._context; - push(valueCursor, context._currentValue); - context._currentValue = updateLanes; - 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, + 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, - renderLanes + workInProgress.stateNode.containerInfo ); - return null !== workInProgress ? workInProgress.sibling : null; - } - push(suspenseStackCursor, suspenseStackCursor.current & 1); - break; - case 19: - updateLanes = 0 !== (renderLanes & workInProgress.childLanes); - if (0 !== (current.flags & 64)) { - if (updateLanes) - return updateSuspenseListComponent( + 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 ); - workInProgress.flags |= 64; - } - context = workInProgress.memoizedState; - null !== context && - ((context.rendering = null), - (context.tail = null), - (context.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 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 + ); } - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7236,22 +7448,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - context = getMaskedContext(workInProgress, contextStackCursor.current); + nextValue = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - context = renderWithHooks( + nextValue = renderWithHooks( null, workInProgress, updateLanes, current, - context, + nextValue, renderLanes ); workInProgress.flags |= 1; if ( - "object" === typeof context && - null !== context && - "function" === typeof context.render && - void 0 === context.$$typeof + "object" === typeof nextValue && + null !== nextValue && + "function" === typeof nextValue.render && + void 0 === nextValue.$$typeof ) { workInProgress.tag = 1; workInProgress.memoizedState = null; @@ -7261,8 +7473,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { pushContextProvider(workInProgress); } else hasContext = !1; workInProgress.memoizedState = - null !== context.state && void 0 !== context.state - ? context.state + null !== nextValue.state && void 0 !== nextValue.state + ? nextValue.state : null; initializeUpdateQueue(workInProgress); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7273,9 +7485,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - context.updater = classComponentUpdater; - workInProgress.stateNode = context; - context._reactInternals = workInProgress; + nextValue.updater = classComponentUpdater; + workInProgress.stateNode = nextValue; + nextValue._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7287,28 +7499,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ); } else (workInProgress.tag = 0), - reconcileChildren(null, workInProgress, context, renderLanes), + reconcileChildren(null, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child); return workInProgress; case 16: - context = workInProgress.elementType; + nextValue = workInProgress.elementType; a: { null !== current && ((current.alternate = null), (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - hasContext = context._init; - context = hasContext(context._payload); - workInProgress.type = context; - hasContext = workInProgress.tag = resolveLazyComponentTag(context); - current = resolveDefaultProps(context, current); + hasContext = nextValue._init; + nextValue = hasContext(nextValue._payload); + workInProgress.type = nextValue; + hasContext = workInProgress.tag = resolveLazyComponentTag(nextValue); + current = resolveDefaultProps(nextValue, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7317,7 +7529,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7326,7 +7538,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - context, + nextValue, current, renderLanes ); @@ -7335,8 +7547,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - context, - resolveDefaultProps(context.type, current), + nextValue, + resolveDefaultProps(nextValue.type, current), updateLanes, renderLanes ); @@ -7344,7 +7556,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - context + + nextValue + ". Lazy element type must resolve to a class or function." ); } @@ -7352,32 +7564,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateFunctionComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateClassComponent( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7388,19 +7600,18 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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." ); - updateLanes = workInProgress.pendingProps; - context = workInProgress.memoizedState; - context = null !== context ? context.element : null; - cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + nextValue = workInProgress.pendingProps; updateLanes = workInProgress.memoizedState.element; - updateLanes === context + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextValue, null, renderLanes); + nextValue = workInProgress.memoizedState.element; + nextValue === updateLanes ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), + : (reconcileChildren(current, workInProgress, nextValue, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7440,16 +7651,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), updateForwardRef( current, workInProgress, updateLanes, - context, + nextValue, renderLanes ) ); @@ -7490,27 +7701,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - context = workInProgress.pendingProps; + nextValue = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = context.value; - var context$jscomp$0 = workInProgress.type._context; - push(valueCursor, context$jscomp$0._currentValue); - context$jscomp$0._currentValue = hasContext; - if (null !== getDerivedStateFromProps) - if ( - ((context$jscomp$0 = getDerivedStateFromProps.value), - (hasContext = objectIs(context$jscomp$0, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits( - context$jscomp$0, - hasContext - ) - : 1073741823) | 0), - 0 === hasContext) - ) { + hasContext = nextValue.value; + push(valueCursor, updateLanes._currentValue); + updateLanes._currentValue = hasContext; + if (null !== getDerivedStateFromProps) { + var oldValue = getDerivedStateFromProps.value; + hasContext = objectIs(oldValue, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits(oldValue, hasContext) + : 1073741823) | 0; + if (0 === hasContext) { if ( - getDerivedStateFromProps.children === context.children && + getDerivedStateFromProps.children === nextValue.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7522,15 +7727,14 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - context$jscomp$0 = workInProgress.child, - null !== context$jscomp$0 && - (context$jscomp$0.return = workInProgress); - null !== context$jscomp$0; + oldValue = workInProgress.child, + null !== oldValue && (oldValue.return = workInProgress); + null !== oldValue; ) { - var list = context$jscomp$0.dependencies; + var list = oldValue.dependencies; if (null !== list) { - getDerivedStateFromProps = context$jscomp$0.child; + getDerivedStateFromProps = oldValue.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7540,20 +7744,24 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - 1 === context$jscomp$0.tag && - ((dependency = createUpdate( - -1, - renderLanes & -renderLanes - )), - (dependency.tag = 2), - enqueueUpdate(context$jscomp$0, dependency)); - context$jscomp$0.lanes |= renderLanes; - dependency = context$jscomp$0.alternate; + if (1 === oldValue.tag) { + dependency = createUpdate(-1, renderLanes & -renderLanes); + dependency.tag = 2; + var updateQueue = oldValue.updateQueue; + if (null !== updateQueue) { + updateQueue = updateQueue.shared; + var pending = updateQueue.pending; + null === pending + ? (dependency.next = dependency) + : ((dependency.next = pending.next), + (pending.next = dependency)); + updateQueue.pending = dependency; + } + } + oldValue.lanes |= renderLanes; + dependency = oldValue.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath( - context$jscomp$0.return, - renderLanes - ); + scheduleWorkOnParentPath(oldValue.return, renderLanes); list.lanes |= renderLanes; break; } @@ -7561,16 +7769,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === context$jscomp$0.tag - ? context$jscomp$0.type === workInProgress.type + 10 === oldValue.tag + ? oldValue.type === workInProgress.type ? null - : context$jscomp$0.child - : context$jscomp$0.child; + : oldValue.child + : oldValue.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = context$jscomp$0; + getDerivedStateFromProps.return = oldValue; else for ( - getDerivedStateFromProps = context$jscomp$0; + getDerivedStateFromProps = oldValue; null !== getDerivedStateFromProps; ) { @@ -7578,20 +7786,21 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - context$jscomp$0 = getDerivedStateFromProps.sibling; - if (null !== context$jscomp$0) { - context$jscomp$0.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = context$jscomp$0; + oldValue = getDerivedStateFromProps.sibling; + if (null !== oldValue) { + oldValue.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = oldValue; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - context$jscomp$0 = getDerivedStateFromProps; + oldValue = getDerivedStateFromProps; } + } reconcileChildren( current, workInProgress, - context.children, + nextValue.children, renderLanes ); workInProgress = workInProgress.child; @@ -7599,28 +7808,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (context = readContext(context, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(context)), + (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(nextValue)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (context = workInProgress.type), + (nextValue = workInProgress.type), (hasContext = resolveDefaultProps( - context, + nextValue, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(context.type, hasContext)), + (hasContext = resolveDefaultProps(nextValue.type, hasContext)), updateMemoComponent( current, workInProgress, - context, + nextValue, hasContext, updateLanes, renderLanes @@ -7638,11 +7847,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (context = workInProgress.pendingProps), - (context = + (nextValue = workInProgress.pendingProps), + (nextValue = workInProgress.elementType === updateLanes - ? context - : resolveDefaultProps(updateLanes, context)), + ? nextValue + : resolveDefaultProps(updateLanes, nextValue)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7652,8 +7861,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, context), - mountClassInstance(workInProgress, updateLanes, context, renderLanes), + constructClassInstance(workInProgress, updateLanes, nextValue), + mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), finishClassComponent( null, workInProgress, @@ -7754,9 +7963,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$103) { + } catch (error$96) { scheduleCallback(99, function() { - throw error$103; + throw error$96; }); } })); @@ -7772,8 +7981,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.flags = 0; - this.lastEffect = this.firstEffect = this.nextEffect = null; + this.subtreeFlags = this.flags = 0; + this.deletions = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7814,11 +8023,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.nextEffect = null), - (workInProgress.firstEffect = null), - (workInProgress.lastEffect = null), + (workInProgress.subtreeFlags = 0), + (workInProgress.deletions = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); + workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7855,15 +8064,18 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 16; + mode |= 8; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - mode |= 1; + 1 <= + (null == pendingProps.unstable_level + ? 1 + : pendingProps.unstable_level) && (mode |= 16); break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 8)), + (type = createFiber(12, pendingProps, key, mode | 4)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -8054,7 +8266,8 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - scheduleUpdateOnFiber(current, lane, eventTime); + element = scheduleUpdateOnFiber(current, lane, eventTime); + null !== element && entangleTransitions(element, current, lane); return lane; } function emptyFindFiberByHostInstance() { @@ -8093,10 +8306,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_930 = { + devToolsConfig$jscomp$inline_986 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.1-454c2211c", + version: "17.0.2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8111,11 +8324,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1148 = { - bundleType: devToolsConfig$jscomp$inline_930.bundleType, - version: devToolsConfig$jscomp$inline_930.version, - rendererPackageName: devToolsConfig$jscomp$inline_930.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_930.rendererConfig, +var internals$jscomp$inline_1282 = { + bundleType: devToolsConfig$jscomp$inline_986.bundleType, + version: devToolsConfig$jscomp$inline_986.version, + rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8130,7 +8343,7 @@ var internals$jscomp$inline_1148 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_930.findFiberByHostInstance || + devToolsConfig$jscomp$inline_986.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -8139,16 +8352,16 @@ var internals$jscomp$inline_1148 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1149 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1283 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1149.isDisabled && - hook$jscomp$inline_1149.supportsFiber + !hook$jscomp$inline_1283.isDisabled && + hook$jscomp$inline_1283.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1149.inject( - internals$jscomp$inline_1148 + (rendererID = hook$jscomp$inline_1283.inject( + internals$jscomp$inline_1282 )), - (injectedHook = hook$jscomp$inline_1149); + (injectedHook = hook$jscomp$inline_1283); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8198,7 +8411,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 8); + isDevToolsPresent && (JSCompiler_inline_result |= 4); JSCompiler_inline_result = createFiber( 3, null, @@ -8207,6 +8420,7 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; + JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 31edc17fd5ee2e..536ce9a6f30b65 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -8,6 +8,8 @@ * @flow */ +'use strict'; + import {BatchedBridge} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; // TODO @sema: Adjust types diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 552b118556aaf0..462abeac94beee 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -8,12 +8,7 @@ * @flow strict */ -import type { - ElementRef, - ElementType, - MixedElement, - AbstractComponent, -} from 'react'; +import type {ElementRef, ElementType, Element, AbstractComponent} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -49,7 +44,7 @@ type AttributeType = // or we allow them to define specific types and use this hack type AnyAttributeType = AttributeType<$FlowFixMe, $FlowFixMe>; -type AttributeConfiguration = $ReadOnly<{ +export type AttributeConfiguration = $ReadOnly<{ [propName: string]: AnyAttributeType, style: $ReadOnly<{ [propName: string]: AnyAttributeType, @@ -185,7 +180,7 @@ export type ReactNativeType = { eventType: string, ): void, render( - element: MixedElement, + element: Element, containerTag: number, callback: ?() => void, ): ?ElementRef, @@ -213,7 +208,7 @@ export type ReactFabricType = { eventType: string, ): void, render( - element: MixedElement, + element: Element, containerTag: number, callback: ?() => void, ): ?ElementRef, diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index 0b3b8cc3d01194..5f219fea65208c 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,6 +8,10 @@ * @flow strict-local */ +/* eslint-disable react-internal/invariant-args */ + +'use strict'; + import {type ViewConfig} from './ReactNativeTypes'; import invariant from 'invariant'; diff --git a/Libraries/Renderer/shims/createReactNativeComponentClass.js b/Libraries/Renderer/shims/createReactNativeComponentClass.js index 0f893dfd24a0b9..f8f4c9284e4c32 100644 --- a/Libraries/Renderer/shims/createReactNativeComponentClass.js +++ b/Libraries/Renderer/shims/createReactNativeComponentClass.js @@ -8,6 +8,8 @@ * @flow strict-local */ +'use strict'; + import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {type ViewConfig} from './ReactNativeTypes'; From d0d2115bee90fa27eaafa3c2b483bba17d03d01c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Fri, 26 Feb 2021 17:10:59 -0800 Subject: [PATCH 13/51] Use renamed `respond-to-issue-based-on-label` GitHub Action. (#30832) Summary: We use the `respond-to-issue-based-on-label` GitHub Action to aid in issue triage. This is a trivial change to ensure we use the new, renamed version of the action. ## Changelog [Internal] - Use renamed GitHub action Pull Request resolved: https://github.com/facebook/react-native/pull/30832 Test Plan: CI Reviewed By: fkgozali Differential Revision: D26702542 Pulled By: hramos fbshipit-source-id: d9d3685f17bfc504fd7e31dee1c6c330e88ef1d1 --- ...actions.yml => respond-to-issue-based-on-label.yml} | 2 +- ...{process-label-actions.yml => on-issue-labeled.yml} | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) rename .github/{label-actions.yml => respond-to-issue-based-on-label.yml} (96%) rename .github/workflows/{process-label-actions.yml => on-issue-labeled.yml} (54%) diff --git a/.github/label-actions.yml b/.github/respond-to-issue-based-on-label.yml similarity index 96% rename from .github/label-actions.yml rename to .github/respond-to-issue-based-on-label.yml index 8cef0647e0068c..65131ff0840db0 100644 --- a/.github/label-actions.yml +++ b/.github/respond-to-issue-based-on-label.yml @@ -1,4 +1,4 @@ -# Configuration for Label Actions - https://github.com/marketplace/actions/label-actions +# Configuration for Respond To Issue Based on Label https://github.com/marketplace/actions/respond-to-issue-based-on-label "Type: Invalid": close: true diff --git a/.github/workflows/process-label-actions.yml b/.github/workflows/on-issue-labeled.yml similarity index 54% rename from .github/workflows/process-label-actions.yml rename to .github/workflows/on-issue-labeled.yml index 2c63100f6e8392..e68682b2ecb71b 100644 --- a/.github/workflows/process-label-actions.yml +++ b/.github/workflows/on-issue-labeled.yml @@ -1,16 +1,16 @@ -name: Label Actions +name: On Issue Labeled # This workflow is triggered when a label is added to an issue. on: issues: types: labeled jobs: - processLabelAction: - name: Process Label Action + respondToIssueBasedOnLabel: + name: Respond to Issue Based on Label runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Process Label Action - uses: hramos/label-actions@v1 + - name: Respond to Issue Based on Label + uses: hramos/respond-to-issue-based-on-label@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} From c9600a310f698a969601c99769afddb72b53a4ac Mon Sep 17 00:00:00 2001 From: Peter Argany Date: Fri, 26 Feb 2021 17:39:24 -0800 Subject: [PATCH 14/51] Connect to RCTInspectorDevServerHelper in bridgeless mode Summary: Changelog: [Internal] Reviewed By: shergin Differential Revision: D26623985 fbshipit-source-id: 98aff018adc0e9aca517d8faebd20fe98e9b708b --- React/CoreModules/RCTDevSettings.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/React/CoreModules/RCTDevSettings.mm b/React/CoreModules/RCTDevSettings.mm index 1fde6654bde424..05ce7049d129b8 100644 --- a/React/CoreModules/RCTDevSettings.mm +++ b/React/CoreModules/RCTDevSettings.mm @@ -166,6 +166,16 @@ - (instancetype)initWithDataSource:(id)dataSource return self; } +#if RCT_ENABLE_INSPECTOR +// In bridgeless mode, `setBridge` is not called, so dev server connection +// must be kicked off here. +- (void)setBundleURL:(NSURL *)bundleURL +{ + _bundleURL = bundleURL; + [RCTInspectorDevServerHelper connectWithBundleURL:_bundleURL]; +} +#endif + - (void)setBridge:(RCTBridge *)bridge { [super setBridge:bridge]; From 2ee5db0fb733fb7cf5d8a234656df70cab5db2bd Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Fri, 26 Feb 2021 19:57:46 -0800 Subject: [PATCH 15/51] Back out "React Native sync for revisions c3e20f1...0cf9fc1" Summary: This diff broke scrolling on Profile React Native surfaces. Please see the task for repro steps. Backing this out. Changelog: [General][Changed] - Back out "React Native sync for revisions c3e20f1...4d28eca" build-break overriding_review_checks_triggers_an_audit_and_retroactive_review Oncall Short Name: fbandroid_sheriff Reviewed By: JoshuaGross Differential Revision: D26708096 fbshipit-source-id: 40f1e7473b8cc041073b2658d46f9500281da99e --- Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 16953 ++++++++-------- .../implementations/ReactFabric-prod.fb.js | 3425 ++-- .../ReactFabric-profiling.fb.js | 3582 ++-- .../ReactNativeRenderer-dev.fb.js | 14801 +++++++------- .../ReactNativeRenderer-prod.fb.js | 3465 ++-- .../ReactNativeRenderer-profiling.fb.js | 3712 ++-- Libraries/Renderer/shims/ReactFabric.js | 2 - Libraries/Renderer/shims/ReactNativeTypes.js | 13 +- .../shims/ReactNativeViewConfigRegistry.js | 4 - .../shims/createReactNativeComponentClass.js | 2 - 11 files changed, 21871 insertions(+), 24090 deletions(-) diff --git a/Libraries/Renderer/REVISION b/Libraries/Renderer/REVISION index bae76f0ce3d759..974273dc6854dd 100644 --- a/Libraries/Renderer/REVISION +++ b/Libraries/Renderer/REVISION @@ -1 +1 @@ -0cf9fc10ba9d47099f3507080dd736054d877a20 \ No newline at end of file +c3e20f18fe37993ddcbf11dccb55663b4c0d02fd \ 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 5d488ee7b2f9d1..4d07117f346fb9 100644 --- a/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; +var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; -var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2493,27 +2493,14 @@ function getFiberCurrentPropsFromNode$1(inst) { // Module provided by RN: var ReactFabricGlobalResponderHandler = { onChange: function(from, to, blockNativeResponder) { - var fromOrTo = from || to; - var isFabric = !!fromOrTo.stateNode.canonical._internalInstanceHandle; - - if (isFabric) { - if (from) { - nativeFabricUIManager.setIsJSResponder(from.stateNode.node, false); - } - - if (to) { - nativeFabricUIManager.setIsJSResponder(to.stateNode.node, true); - } + if (to !== null) { + var tag = to.stateNode.canonical._nativeTag; + ReactNativePrivateInterface.UIManager.setJSResponder( + tag, + blockNativeResponder + ); } else { - if (to !== null) { - var tag = to.stateNode.canonical._nativeTag; - ReactNativePrivateInterface.UIManager.setJSResponder( - tag, - blockNativeResponder - ); - } else { - ReactNativePrivateInterface.UIManager.clearJSResponder(); - } + ReactNativePrivateInterface.UIManager.clearJSResponder(); } } }; @@ -2560,12 +2547,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; +var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; -var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2581,12 +2568,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); + REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2660,9 +2647,6 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - - case REACT_CACHE_TYPE: - return "Cache"; } if (typeof type === "object") { @@ -2700,10 +2684,8 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; -var enableLazyElements = false; var warnAboutStringRefs = false; var enableNewReconciler = false; -var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -2721,84 +2703,53 @@ var Update = 4; var PlacementAndUpdate = /* */ - Placement | Update; -var ChildDeletion = - /* */ - 16; + 6; +var Deletion = + /* */ + 8; var ContentReset = /* */ - 32; + 16; var Callback = /* */ - 64; + 32; var DidCapture = /* */ - 128; + 64; var Ref = /* */ - 256; + 128; var Snapshot = /* */ - 512; + 256; var Passive = /* */ - 1024; + 512; var Hydrating = /* */ - 2048; + 1024; var HydratingAndUpdate = /* */ - Hydrating | Update; -var Visibility = - /* */ - 4096; + 1028; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 8191; // These are not really side effects, but we still reuse this field. + 4095; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 8192; + 4096; var ShouldCapture = /* */ - 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 32768; + 16384; var ForceUpdateForLegacySuspense = /* */ - 65536; // Static tags describe aspects of a fiber that are not specific to a render, -// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). -// This enables us to defer more work in the unmount case, -// since we can defer traversing the tree during layout to look for Passive effects, -// and instead rely on the static flag as a signal that there may be cleanup work. - -var PassiveStatic = - /* */ - 131072; // These flags allow us to traverse to fibers that have effects on mount -// don't contain effects, by checking subtreeFlags. - -var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity - // flag logic (see #20043) - Update | Snapshot | 0; -var MutationMask = - Placement | - Update | - ChildDeletion | - ContentReset | - Ref | - Hydrating | - Visibility; -var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask - -var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. -// This allows certain concepts to persist without recalculting them, -// e.g. whether a subtree contains passive effects or portals. - -var StaticMask = PassiveStatic; + 32768; // Static tags describe aspects of a fiber that are not specific to a render, var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3038,28 +2989,38 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); - return currentParent !== null - ? findCurrentHostFiberImpl(currentParent) - : null; -} -function findCurrentHostFiberImpl(node) { - // Next we'll drill down this component to find the first HostComponent/Text. - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } + if (!currentParent) { + return null; + } // Next we'll drill down this component to find the first HostComponent/Text. - var child = node.child; + var node = currentParent; - while (child !== null) { - var match = findCurrentHostFiberImpl(child); + while (true) { + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } else if (node.child) { + node.child.return = node; + node = node.child; + continue; + } - if (match !== null) { - return match; + if (node === currentParent) { + return null; } - child = child.sibling; - } + while (!node.sibling) { + if (!node.return || node.return === currentParent) { + return null; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } // Flow needs the return null here, but ESLint complains about it. + // eslint-disable-next-line no-unreachable return null; } @@ -3728,3808 +3689,3630 @@ function dispatchEvent(target, topLevelType, nativeEvent) { // where it would do it. } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +// can re-export everything from this module. -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { +function shim() { + { throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." ); } -} - -// Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. +} // Mutation (when unsupported) -var NoPriority = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. +var supportsMutation = false; +var commitMount = shim; +var clearContainer = shim; -var now = - initialTimeMs < 10000 - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority; +// can re-export everything from this module. - case Scheduler_UserBlockingPriority: - return UserBlockingPriority; +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$1; +var isSuspenseInstanceFallback = shim$1; +var hydrateTextInstance = shim$1; - case Scheduler_NormalPriority: - return NormalPriority; +var _nativeFabricUIManage = nativeFabricUIManager, + createNode = _nativeFabricUIManage.createNode, + cloneNode = _nativeFabricUIManage.cloneNode, + cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, + cloneNodeWithNewChildrenAndProps = + _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, + cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, + createChildNodeSet = _nativeFabricUIManage.createChildSet, + appendChildNode = _nativeFabricUIManage.appendChild, + appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, + completeRoot = _nativeFabricUIManage.completeRoot, + registerEventHandler = _nativeFabricUIManage.registerEventHandler, + fabricMeasure = _nativeFabricUIManage.measure, + fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, + fabricMeasureLayout = _nativeFabricUIManage.measureLayout, + sendAccessibilityEvent = _nativeFabricUIManage.sendAccessibilityEvent; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. +// This means that they never overlap. - case Scheduler_LowPriority: - return LowPriority; +var nextReactTag = 2; - case Scheduler_IdlePriority: - return IdlePriority; +// TODO: Remove this conditional once all changes have propagated. +if (registerEventHandler) { + /** + * Register the event emitter with the native bridge + */ + registerEventHandler(dispatchEvent); +} +/** + * This is used for refs on host components. + */ - default: { - throw Error("Unknown priority level."); - } +var ReactFabricHostComponent = /*#__PURE__*/ (function() { + function ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ) { + this._nativeTag = tag; + this.viewConfig = viewConfig; + this.currentProps = props; + this._internalInstanceHandle = internalInstanceHandle; } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority: - return Scheduler_ImmediatePriority; + var _proto = ReactFabricHostComponent.prototype; - case UserBlockingPriority: - return Scheduler_UserBlockingPriority; + _proto.blur = function blur() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; - case NormalPriority: - return Scheduler_NormalPriority; + _proto.focus = function focus() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; - case LowPriority: - return Scheduler_LowPriority; + _proto.measure = function measure(callback) { + fabricMeasure( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - case IdlePriority: - return Scheduler_IdlePriority; + _proto.measureInWindow = function measureInWindow(callback) { + fabricMeasureInWindow( + this._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; - default: { - throw Error("Unknown priority level."); + _proto.measureLayout = function measureLayout( + relativeToNativeNode, + onSuccess, + onFail + ) /* currently unused */ + { + if ( + typeof relativeToNativeNode === "number" || + !(relativeToNativeNode instanceof ReactFabricHostComponent) + ) { + { + error( + "Warning: ref.measureLayout must be called with a ref to a native component." + ); + } + + return; } - } -} -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); -} -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we - // forget to explicitly flush. + fabricMeasureLayout( + this._internalInstanceHandle.stateNode.node, + relativeToNativeNode._internalInstanceHandle.stateNode.node, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) + ); + }; + _proto.setNativeProps = function setNativeProps(nativeProps) { { - // Flush the queue in the next tick. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); + error("Warning: setNativeProps is not currently supported in Fabric"); } - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); - } -} -function cancelCallback(callbackNode) { - Scheduler_cancelCallback(callbackNode); -} -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - - flushSyncCallbackQueueImpl(); -} - -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; + return; + }; - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick + return ReactFabricHostComponent; +})(); // eslint-disable-next-line no-unused-expressions +function appendInitialChild(parentInstance, child) { + appendChildNode(parentInstance.node, child.node); +} +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = nextReactTag; + nextReactTag += 2; + var viewConfig = getViewConfigForType(type); - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] ); - throw error; - } finally { - isFlushingSyncQueue = false; } } } -} - -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. -// If those values are changed that package should be rebuilt and redeployed. - -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLane = - /* */ - 8; -var InputContinuousHydrationLane = - /* */ - 16; -var InputContinuousLane = - /* */ - 32; -var DefaultHydrationLane = - /* */ - 64; -var DefaultLane = - /* */ - 128; -var TransitionHydrationLane = - /* */ - 256; -var TransitionLanes = - /* */ - 8388096; -var TransitionLane1 = - /* */ - 512; -var TransitionLane2 = - /* */ - 1024; -var TransitionLane3 = - /* */ - 2048; -var TransitionLane4 = - /* */ - 4096; -var TransitionLane5 = - /* */ - 8192; -var TransitionLane6 = - /* */ - 16384; -var TransitionLane7 = - /* */ - 32768; -var TransitionLane8 = - /* */ - 65536; -var TransitionLane9 = - /* */ - 131072; -var TransitionLane10 = - /* */ - 262144; -var TransitionLane11 = - /* */ - 524288; -var TransitionLane12 = - /* */ - 1048576; -var TransitionLane13 = - /* */ - 2097152; -var TransitionLane14 = - /* */ - 4194304; -var RetryLanes = - /* */ - 125829120; -var RetryLane1 = - /* */ - 8388608; -var RetryLane2 = - /* */ - 16777216; -var RetryLane3 = - /* */ - 33554432; -var RetryLane4 = - /* */ - 67108864; -var SomeRetryLane = RetryLane1; -var SelectiveHydrationLane = - /* */ - 134217728; -var NonIdleLanes = - /* */ - 268435455; -var IdleHydrationLane = - /* */ - 268435456; -var IdleLane = - /* */ - 536870912; -var OffscreenLane = - /* */ - 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) -var NoTimestamp = -1; -var nextTransitionLane = TransitionLane1; -var nextRetryLane = RetryLane1; -// Used by getHighestPriorityLanes and getNextLanes: - -var return_highestLanePriority = DefaultLanePriority; - -function getHighestPriorityLanes(lanes) { - switch (getHighestPriorityLane(lanes)) { - case SyncLane: - return_highestLanePriority = SyncLanePriority; - return SyncLane; - - case SyncBatchedLane: - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - - case InputDiscreteHydrationLane: - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - - case InputDiscreteLane: - return_highestLanePriority = InputDiscreteLanePriority; - return InputDiscreteLane; - - case InputContinuousHydrationLane: - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - - case InputContinuousLane: - return_highestLanePriority = InputContinuousLanePriority; - return InputContinuousLane; - - case DefaultHydrationLane: - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - - case DefaultLane: - return_highestLanePriority = DefaultLanePriority; - return DefaultLane; - - case TransitionHydrationLane: - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; - - case TransitionLane1: - case TransitionLane2: - case TransitionLane3: - case TransitionLane4: - case TransitionLane5: - case TransitionLane6: - case TransitionLane7: - case TransitionLane8: - case TransitionLane9: - case TransitionLane10: - case TransitionLane11: - case TransitionLane12: - case TransitionLane13: - case TransitionLane14: - return_highestLanePriority = TransitionPriority; - return lanes & TransitionLanes; - - case RetryLane1: - case RetryLane2: - case RetryLane3: - case RetryLane4: - return_highestLanePriority = RetryLanePriority; - return lanes & RetryLanes; - - case SelectiveHydrationLane: - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; - - case IdleHydrationLane: - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; - - case IdleLane: - return_highestLanePriority = IdleLanePriority; - return IdleLane; - - case OffscreenLane: - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; - - default: - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - return_highestLanePriority = DefaultLanePriority; - return lanes; - } + var updatePayload = create(props, viewConfig.validAttributes); + var node = createNode( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload, // props + internalInstanceHandle // internalInstanceHandle + ); + var component = new ReactFabricHostComponent( + tag, + viewConfig, + props, + internalInstanceHandle + ); + return { + node: node, + canonical: component + }; } +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); + } -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; - - case IdlePriority: - return IdleLanePriority; + var tag = nextReactTag; + nextReactTag += 2; + var node = createNode( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + }, // props + internalInstanceHandle // instance handle + ); + return { + node: node + }; +} +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; - default: - return NoLanePriority; + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; - - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; - - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; - - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; - - case NoLanePriority: - return NoPriority; - - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } - } +function getPublicInstance(instance) { + return instance.canonical; } -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; - - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; - } +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + var viewConfig = instance.canonical.viewConfig; + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props + // in the commit phase but there is no host config hook to do it yet. + // So instead we hack it by updating it in the render phase. - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. + instance.canonical.currentProps = newProps; + return updatePayload; +} +function resetAfterCommit(containerInfo) { + // Noop +} +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} // The Fabric renderer is secondary to the existing React Native renderer. +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; // ------------------- +function cloneInstance( + instance, + updatePayload, + type, + oldProps, + newProps, + internalInstanceHandle, + keepChildren, + recyclableInstance +) { + var node = instance.node; + var clone; - if (expiredLanes !== NoLanes) { - // TODO: Should entangle with SyncLane - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; + if (keepChildren) { + if (updatePayload !== null) { + clone = cloneNodeWithNewProps(node, updatePayload); + } else { + clone = cloneNode(node); + } } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } + if (updatePayload !== null) { + clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; - - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; - } - } + clone = cloneNodeWithNewChildren(node); } } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. + return { + node: clone, + canonical: instance.canonical + }; +} +function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { + var viewConfig = instance.canonical.viewConfig; + var node = instance.node; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + return { + node: cloneNodeWithNewProps(node, updatePayload), + canonical: instance.canonical + }; +} +function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { + throw new Error("Not yet implemented."); +} +function createContainerChildSet(container) { + return createChildNodeSet(container); +} +function appendChildToContainerChildSet(childSet, child) { + appendChildNodeToSet(childSet, child.node); +} +function finalizeContainerChildren(container, newChildren) { + completeRoot(container, newChildren); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - if ( - nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The - // only difference between default updates and transition updates is that - // default updates do not support refresh transitions. - (nextLanePriority === DefaultLanePriority && - wipLanePriority === TransitionPriority) - ) { - // Keep working on the existing in-progress tree. Do not interrupt. - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; - } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // TODO: Reconsider this. The counter-argument is that the partial work - // represents an intermediate state, which we don't want to show to the user. - // And by spending extra time finishing it, we're increasing the amount of - // time it takes to show the final state, which is what they are actually - // waiting for. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. +function disabledLog() {} - var entangledLanes = root.entangledLanes; +disabledLog.__reactDisabledLog = true; +function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } - } - return nextLanes; + disabledDepth++; + } } -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; - - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; +function reenableLogs() { + { + disabledDepth--; - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ } - lanes &= ~lane; + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); + } } - - return mostRecentEventTime; } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } + + return describeComponentFrame(name, source, ownerName); } } +var componentFrameCache; -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - var lanes = pendingLanes; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + + if (match) { + var pathBeforeSlash = match[1]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; + } } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; } - lanes &= ~lane; + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; - } + return "\n in " + (name || "Unknown") + sourceInfo; +} - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); } - - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; -} -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; } -function isTransitionLane(lane) { - return (lane & TransitionLanes) !== 0; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority) { - switch (lanePriority) { - case NoLanePriority: - break; +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; + } - case SyncLanePriority: - return SyncLane; + var name = fn.displayName || fn.name || null; + var ownerName = null; - case SyncBatchedLanePriority: - return SyncBatchedLane; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - case InputDiscreteLanePriority: - return InputDiscreteLane; + return describeComponentFrame(name, source, ownerName); + } +} - case InputContinuousLanePriority: - return InputContinuousLane; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } - case DefaultLanePriority: - return DefaultLane; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); + } + } - case TransitionPriority: // Should be handled by findTransitionLane instead + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); + } - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - case IdleLanePriority: - return IdleLane; + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } - { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function claimNextTransitionLane() { - // Cycle through the lanes, assigning each new transition to the next lane. - // In most cases, this means every transition gets its own lane, until we - // run out of lanes and cycle back to the beginning. - var lane = nextTransitionLane; - nextTransitionLane <<= 1; + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); - if ((nextTransitionLane & TransitionLanes) === 0) { - nextTransitionLane = TransitionLane1; - } + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - return lane; -} -function claimNextRetryLane() { - var lane = nextRetryLane; - nextRetryLane <<= 1; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - if ((nextRetryLane & RetryLanes) === 0) { - nextRetryLane = RetryLane1; + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} + } + } } - return lane; + return ""; } -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); -} - -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } + } } -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} -function intersectLanes(a, b) { - return a & b; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); - } + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update - // could unblock them. Clear the suspended lanes so that we can try rendering - // them again. - // - // TODO: We really only need to unsuspend only lanes that are in the - // `subtreeLanes` of the updated fiber, or the update lanes of the return - // path. This would exclude suspended updates in an unrelated sibling tree, - // since there's no way for this update to unblock it. - // - // We don't do this if the incoming update is idle, because we never process - // idle updates until after all the regular updates have finished; there's no - // way it could unblock a transition. + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - if (updateLane !== IdleLane) { - root.suspendedLanes = NoLanes; - root.pingedLanes = NoLanes; - } + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. + setCurrentlyValidatingElement(null); + } - eventTimes[index] = eventTime; -} -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; + error("Failed %s type: %s", location, error$1.message); - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; + setCurrentlyValidatingElement(null); + } + } + } } } -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function markRootExpired(root, expiredLanes) { - root.expiredLanes |= expiredLanes & root.pendingLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLane) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; +var valueStack = []; +var fiberStack; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work +{ + fiberStack = []; +} - var lanes = noLongerPendingLanes; +var index = -1; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } +function createCursor(defaultValue) { + return { + current: defaultValue + }; } -function markRootEntangled(root, entangledLanes) { - // In addition to entangling each of the given lanes with each other, we also - // have to consider _transitive_ entanglements. For each lane that is already - // entangled with *any* of the given lanes, that lane is now transitively - // entangled with *all* the given lanes. - // - // Translated: If C is entangled with A, then entangling A with B also - // entangles C with B. - // - // If this is hard to grasp, it might help to intentionally break this - // function and look at the tests that fail in ReactTransition-test.js. Try - // commenting out one of the conditions below. - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - var entanglements = root.entanglements; - var lanes = rootEntangledLanes; - while (lanes) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); + } - if ( - // Is this one of the newly entangled lanes? - (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? - (entanglements[index] & entangledLanes) - ) { - entanglements[index] |= entangledLanes; + return; + } + + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); } + } - lanes &= ~lane; + cursor.current = valueStack[index]; + valueStack[index] = null; + + { + fiberStack[index] = null; } + + index--; } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -var log = Math.log; -var LN2 = Math.LN2; +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; + { + fiberStack[index] = fiber; } - return (31 - ((log(lanes) / LN2) | 0)) | 0; + cursor.current = value; } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now$1 = Scheduler.unstable_now; +var warnedAboutMissingGetChildContext; { - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } + warnedAboutMissingGetChildContext = {}; } -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// can re-export everything from this module. +var emptyContextObject = {}; -function shim() { - { - throw Error( - "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." - ); - } -} // Mutation (when unsupported) +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. -var supportsMutation = false; -var commitMount = shim; -var clearContainer = shim; +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. -// can re-export everything from this module. +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. -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$1; -var isSuspenseInstanceFallback = shim$1; -var hydrateTextInstance = shim$1; - -var _nativeFabricUIManage = nativeFabricUIManager, - createNode = _nativeFabricUIManage.createNode, - cloneNode = _nativeFabricUIManage.cloneNode, - cloneNodeWithNewChildren = _nativeFabricUIManage.cloneNodeWithNewChildren, - cloneNodeWithNewChildrenAndProps = - _nativeFabricUIManage.cloneNodeWithNewChildrenAndProps, - cloneNodeWithNewProps = _nativeFabricUIManage.cloneNodeWithNewProps, - createChildNodeSet = _nativeFabricUIManage.createChildSet, - appendChildNode = _nativeFabricUIManage.appendChild, - appendChildNodeToSet = _nativeFabricUIManage.appendChildToSet, - completeRoot = _nativeFabricUIManage.completeRoot, - registerEventHandler = _nativeFabricUIManage.registerEventHandler, - fabricMeasure = _nativeFabricUIManage.measure, - fabricMeasureInWindow = _nativeFabricUIManage.measureInWindow, - fabricMeasureLayout = _nativeFabricUIManage.measureLayout; -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. -// This means that they never overlap. +var previousContext = emptyContextObject; -var nextReactTag = 2; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + } -// TODO: Remove this conditional once all changes have propagated. -if (registerEventHandler) { - /** - * Register the event emitter with the native bridge - */ - registerEventHandler(dispatchEvent); + return contextStackCursor.current; + } } -/** - * This is used for refs on host components. - */ -var ReactFabricHostComponent = /*#__PURE__*/ (function() { - function ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ) { - this._nativeTag = tag; - this.viewConfig = viewConfig; - this.currentProps = props; - this._internalInstanceHandle = internalInstanceHandle; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; } +} - var _proto = ReactFabricHostComponent.prototype; - - _proto.blur = function blur() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - - _proto.focus = function focus() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; - _proto.measure = function measure(callback) { - fabricMeasure( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. - _proto.measureInWindow = function measureInWindow(callback) { - fabricMeasureInWindow( - this._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; + var instance = workInProgress.stateNode; - _proto.measureLayout = function measureLayout( - relativeToNativeNode, - onSuccess, - onFail - ) /* currently unused */ - { if ( - typeof relativeToNativeNode === "number" || - !(relativeToNativeNode instanceof ReactFabricHostComponent) + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext ) { - { - error( - "Warning: ref.measureLayout must be called with a ref to a native component." - ); - } - - return; + return instance.__reactInternalMemoizedMaskedChildContext; } - fabricMeasureLayout( - this._internalInstanceHandle.stateNode.node, - relativeToNativeNode._internalInstanceHandle.stateNode.node, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; + var context = {}; - _proto.setNativeProps = function setNativeProps(nativeProps) { - { - error("Warning: setNativeProps is not currently supported in Fabric"); + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; } - return; - }; + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. - return ReactFabricHostComponent; -})(); // eslint-disable-next-line no-unused-expressions -function appendInitialChild(parentInstance, child) { - appendChildNode(parentInstance.node, child.node); + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } + + return context; + } } -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = nextReactTag; - nextReactTag += 2; - var viewConfig = getViewConfigForType(type); +function hasContextChanged() { { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } - } + return didPerformWorkStackCursor.current; } - - var updatePayload = create(props, viewConfig.validAttributes); - var node = createNode( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload, // props - internalInstanceHandle // internalInstanceHandle - ); - var component = new ReactFabricHostComponent( - tag, - viewConfig, - props, - internalInstanceHandle - ); - return { - node: node, - canonical: component - }; } -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); + +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; } +} - var tag = nextReactTag; - nextReactTag += 2; - var node = createNode( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - }, // props - internalInstanceHandle // instance handle - ); - return { - node: node - }; +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; + +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; +function pushTopLevelContextObject(fiber, context, didChange) { + { + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + } + + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } } -function getPublicInstance(instance) { - return instance.canonical; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - var viewConfig = instance.canonical.viewConfig; - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // TODO: If the event handlers have changed, we need to update the current props - // in the commit phase but there is no host config hook to do it yet. - // So instead we hack it by updating it in the render phase. - instance.canonical.currentProps = newProps; - return updatePayload; -} -function resetAfterCommit(containerInfo) { - // Noop -} -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; // ------------------- -function cloneInstance( - instance, - updatePayload, - type, - oldProps, - newProps, - internalInstanceHandle, - keepChildren, - recyclableInstance -) { - var node = instance.node; - var clone; +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. - if (keepChildren) { - if (updatePayload !== null) { - clone = cloneNodeWithNewProps(node, updatePayload); - } else { - clone = cloneNode(node); - } - } else { - if (updatePayload !== null) { - clone = cloneNodeWithNewChildrenAndProps(node, updatePayload); - } else { - clone = cloneNodeWithNewChildren(node); - } - } + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; - return { - node: clone, - canonical: instance.canonical - }; -} -function cloneHiddenInstance(instance, type, props, internalInstanceHandle) { - var viewConfig = instance.canonical.viewConfig; - var node = instance.node; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - return { - node: cloneNodeWithNewProps(node, updatePayload), - canonical: instance.canonical - }; -} -function cloneHiddenTextInstance(instance, text, internalInstanceHandle) { - throw new Error("Not yet implemented."); -} -function createContainerChildSet(container) { - return createChildNodeSet(container); -} -function appendChildToContainerChildSet(childSet, child) { - appendChildNodeToSet(childSet, child.node); -} -function finalizeContainerChildren(container, newChildren) { - completeRoot(container, newChildren); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } -function disabledLog() {} + return parentContext; + } -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + var childContext = instance.getChildContext(); - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); } - disabledDepth++; + return Object.assign({}, parentContext, childContext); } } -function reenableLogs() { - { - disabledDepth--; - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); - } + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress + ); + return true; } } -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { +function invalidateContextProvider(workInProgress, type, didChange) { { - var ownerName = null; + var instance = workInProgress.stateNode; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); } - return describeComponentFrame(name, source, ownerName); - } -} -var componentFrameCache; - -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; - - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". - - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. - if (match) { - var pathBeforeSlash = match[1]; + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; - } - } + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); } - - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; } - - return "\n in " + (name || "Unknown") + sourceInfo; } -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); - } -} -function describeFunctionComponentFrame(fn, source, ownerFn) { +function findCurrentUnmaskedContext(fiber) { { - if (!fn) { - return ""; + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); } - var name = fn.displayName || fn.name || null; - var ownerName = null; + var node = fiber; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; - return describeComponentFrame(name, source, ownerName); - } -} + case ClassComponent: { + var Component = node.type; -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; - } + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } + + break; + } + } + + node = node.return; + } while (node !== null); - if (typeof type === "function") { { - return describeFunctionComponentFrame(type, source, ownerFn); + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); } } +} - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; } - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + return true; + } - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); + } + } // DevTools exists + + return true; +} +function onScheduleRoot(root, children) { + { + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; + + error("React instrumentation encountered an error: %s", err); + } } } } - - return ""; } +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); + error("React instrumentation encountered an error: %s", err); + } + } } } } +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); - - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. + error("React instrumentation encountered an error: %s", err); + } + } + } + } +} - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now = Scheduler.unstable_now; - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } - - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); + } +} +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - setCurrentlyValidatingElement(null); - } +var NoPriority = 90; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLanes = + /* */ + 24; +var InputContinuousHydrationLane = + /* */ + 32; +var InputContinuousLanes = + /* */ + 192; +var DefaultHydrationLane = + /* */ + 256; +var DefaultLanes = + /* */ + 3584; +var TransitionHydrationLane = + /* */ + 4096; +var TransitionLanes = + /* */ + 4186112; +var RetryLanes = + /* */ + 62914560; +var SomeRetryLane = + /* */ + 33554432; +var SelectiveHydrationLane = + /* */ + 67108864; +var NonIdleLanes = + /* */ + 134217727; +var IdleHydrationLane = + /* */ + 134217728; +var IdleLanes = + /* */ + 805306368; +var OffscreenLane = + /* */ + 1073741824; +var NoTimestamp = -1; +// Used by getHighestPriorityLanes and getNextLanes: - error("Failed %s type: %s", location, error$1.message); +var return_highestLanePriority = DefaultLanePriority; - setCurrentlyValidatingElement(null); - } - } - } +function getHighestPriorityLanes(lanes) { + if ((SyncLane & lanes) !== NoLanes) { + return_highestLanePriority = SyncLanePriority; + return SyncLane; } -} - -var valueStack = []; -var fiberStack; - -{ - fiberStack = []; -} -var index = -1; + if ((SyncBatchedLane & lanes) !== NoLanes) { + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; + } -function createCursor(defaultValue) { - return { - current: defaultValue - }; -} + if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; + } -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } + var inputDiscreteLanes = InputDiscreteLanes & lanes; - return; + if (inputDiscreteLanes !== NoLanes) { + return_highestLanePriority = InputDiscreteLanePriority; + return inputDiscreteLanes; } - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } + if ((lanes & InputContinuousHydrationLane) !== NoLanes) { + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; } - cursor.current = valueStack[index]; - valueStack[index] = null; + var inputContinuousLanes = InputContinuousLanes & lanes; - { - fiberStack[index] = null; + if (inputContinuousLanes !== NoLanes) { + return_highestLanePriority = InputContinuousLanePriority; + return inputContinuousLanes; } - index--; -} + if ((lanes & DefaultHydrationLane) !== NoLanes) { + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + } -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; + var defaultLanes = DefaultLanes & lanes; - { - fiberStack[index] = fiber; + if (defaultLanes !== NoLanes) { + return_highestLanePriority = DefaultLanePriority; + return defaultLanes; } - cursor.current = value; -} - -var warnedAboutMissingGetChildContext; + if ((lanes & TransitionHydrationLane) !== NoLanes) { + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + } -{ - warnedAboutMissingGetChildContext = {}; -} + var transitionLanes = TransitionLanes & lanes; -var emptyContextObject = {}; + if (transitionLanes !== NoLanes) { + return_highestLanePriority = TransitionPriority; + return transitionLanes; + } -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. + var retryLanes = RetryLanes & lanes; -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + if (retryLanes !== NoLanes) { + return_highestLanePriority = RetryLanePriority; + return retryLanes; + } -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + if (lanes & SelectiveHydrationLane) { + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + } -var previousContext = emptyContextObject; + if ((lanes & IdleHydrationLane) !== NoLanes) { + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + } -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; - } + var idleLanes = IdleLanes & lanes; - return contextStackCursor.current; + if (idleLanes !== NoLanes) { + return_highestLanePriority = IdleLanePriority; + return idleLanes; } -} -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; + if ((OffscreenLane & lanes) !== NoLanes) { + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; } -} -function getMaskedContext(workInProgress, unmaskedContext) { { - var type = workInProgress.type; - var contextTypes = type.contextTypes; - - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. - - var instance = workInProgress.stateNode; + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; - } + return_highestLanePriority = DefaultLanePriority; + return lanes; +} - var context = {}; +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + case UserBlockingPriority: + return InputContinuousLanePriority; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); - } + case IdlePriority: + return IdleLanePriority; - return context; + default: + return NoLanePriority; } } +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; - } -} + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; - } -} + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } -} + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; -function popTopLevelContextObject(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } -} + case NoLanePriority: + return NoPriority; -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { + default: { throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + "Invalid update priority: " + lanePriority + ". This is a bug in React." ); } - - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); } } +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. - - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; + } - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } - } + if (expiredLanes !== NoLanes) { + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; - return parentContext; - } + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; - var childContext = instance.getChildContext(); + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; + } } - } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } + } } - - return Object.assign({}, parentContext, childContext); } -} - -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If there are higher priority lanes, we'll include them even if they + // are suspended. - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; - } -} + nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); + if (nextLanePriority <= wipLanePriority) { + return wipLanes; + } else { + return_highestLanePriority = nextLanePriority; } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. + var entangledLanes = root.entangledLanes; - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; } } + + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; + + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; } - var node = fiber; + lanes &= ~lane; + } - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; + return mostRecentEventTime; +} - case ClassComponent: { - var Component = node.type; +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; + } +} - break; - } - } +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. - node = node.return; - } while (node !== null); + var lanes = pendingLanes; - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; + + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); + } + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } + + lanes &= ~lane; } -} +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; +} +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; - } +function findUpdateLane(lanePriority, wipLanes) { + switch (lanePriority) { + case NoLanePriority: + break; - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. + case SyncLanePriority: + return SyncLane; - return true; - } + case SyncBatchedLanePriority: + return SyncBatchedLane; - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + case InputDiscreteLanePriority: { + var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); + if (_lane === NoLane) { + // Shift to the next priority level + return findUpdateLane(InputContinuousLanePriority, wipLanes); + } + + return _lane; } - } // DevTools exists - return true; -} -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; + case InputContinuousLanePriority: { + var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); - error("React instrumentation encountered an error: %s", err); - } + if (_lane2 === NoLane) { + // Shift to the next priority level + return findUpdateLane(DefaultLanePriority, wipLanes); } + + return _lane2; } - } -} -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; + case DefaultLanePriority: { + var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); - error("React instrumentation encountered an error: %s", err); + if (_lane3 === NoLane) { + // If all the default lanes are already being worked on, look for a + // lane in the transition range. + _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); + + if (_lane3 === NoLane) { + // All the transition lanes are taken, too. This should be very + // rare, but as a last resort, pick a default lane. This will have + // the effect of interrupting the current work-in-progress render. + _lane3 = pickArbitraryLane(DefaultLanes); } } + + return _lane3; } - } -} -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - error("React instrumentation encountered an error: %s", err); - } + case TransitionPriority: // Should be handled by findTransitionLane instead + + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; + + case IdleLanePriority: + var lane = pickArbitraryLane(IdleLanes & ~wipLanes); + + if (lane === NoLane) { + lane = pickArbitraryLane(IdleLanes); } - } + + return lane; } -} -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. + { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } +} // To ensure consistency across multiple updates in the same event, this should +// be pure function, so that it always returns the same lane for given inputs. -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. +function findTransitionLane(wipLanes, pendingLanes) { + // First look for lanes that are completely unclaimed, i.e. have no + // pending work. + var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; + if (lane === NoLane) { + // If all lanes have pending work, look for a lane that isn't currently + // being worked on. + lane = pickArbitraryLane(TransitionLanes & ~wipLanes); -// TODO: this is special because it gets imported during build. -// -// TODO: 17.0.2 has not been released to NPM; -// It exists as a placeholder so that DevTools can support work tag changes between releases. -// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js -var ReactVersion = "17.0.2"; + if (lane === NoLane) { + // If everything is being worked on, pick any lane. This has the + // effect of interrupting the current work-in-progress. + lane = pickArbitraryLane(TransitionLanes); + } + } -var NoMode = - /* */ - 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead + return lane; +} // To ensure consistency across multiple updates in the same event, this should +// be pure function, so that it always returns the same lane for given inputs. -var BlockingMode = - /* */ - 1; -var ConcurrentMode = - /* */ - 2; -var ProfileMode = - /* */ - 4; -var DebugTracingMode = - /* */ - 8; -var StrictLegacyMode = - /* */ - 16; +function findRetryLane(wipLanes) { + // This is a fork of `findUpdateLane` designed specifically for Suspense + // "retries" — a special update that attempts to flip a Suspense boundary + // from its placeholder state to its primary/resolved state. + var lane = pickArbitraryLane(RetryLanes & ~wipLanes); -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -var NoTransition = 0; -function requestCurrentTransition() { - return ReactCurrentBatchConfig.transition; + if (lane === NoLane) { + lane = pickArbitraryLane(RetryLanes); + } + + return lane; } -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - return ( - (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare - ); +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -var objectIs = typeof Object.is === "function" ? Object.is : is; +function getLowestPriorityLane(lanes) { + // This finds the most significant non-zero bit. + var index = 31 - clz32(lanes); + return index < 0 ? NoLanes : 1 << index; +} -var hasOwnProperty = Object.prototype.hasOwnProperty; -/** - * Performs equality by iterating through keys on an object and returning false - * when any key has values which are not strictly equal between the arguments. - * Returns true when the values of all keys are strictly equal. - */ - -function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { - return true; - } - - if ( - typeof objA !== "object" || - objA === null || - typeof objB !== "object" || - objB === null - ) { - return false; - } - - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } // Test for A's keys different from B. - - for (var i = 0; i < keysA.length; i++) { - if ( - !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) - ) { - return false; - } - } +function getEqualOrHigherPriorityLanes(lanes) { + return (getLowestPriorityLane(lanes) << 1) - 1; +} - return true; +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); } -function describeFiber(fiber) { - var owner = fiber._debugOwner ? fiber._debugOwner.type : null; - var source = fiber._debugSource; +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); +} - switch (fiber.tag) { - case HostComponent: - return describeBuiltInComponentFrame(fiber.type, source, owner); +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); +} - case LazyComponent: - return describeBuiltInComponentFrame("Lazy", source, owner); +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). - case SuspenseComponent: - return describeBuiltInComponentFrame("Suspense", source, owner); +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; - case SuspenseListComponent: - return describeBuiltInComponentFrame("SuspenseList", source, owner); + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } - case FunctionComponent: - case IndeterminateComponent: - case SimpleMemoComponent: - return describeFunctionComponentFrame(fiber.type, source, owner); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But + // it's not practical to try every single possible combination. We need a + // heuristic to decide which lanes to attempt to render, and in which batches. + // For now, we use the same heuristic as in the old ExpirationTimes model: + // retry any lane at equal or lower priority, but don't try updates at higher + // priority without also including the lower priority updates. This works well + // when considering updates across different priority levels, but isn't + // sufficient for updates within the same priority, since we want to treat + // those updates as parallel. + // Unsuspend any update at equal or lower priority. + + var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 + + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. - case ForwardRef: - return describeFunctionComponentFrame(fiber.type.render, source, owner); + eventTimes[index] = eventTime; +} +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - case ClassComponent: - return describeClassComponentFrame(fiber.type, source, owner); + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; - default: - return ""; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; +} +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLanes) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -function getStackByFiberInDevAndProd(workInProgress) { - try { - var info = ""; - var node = workInProgress; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work - do { - info += describeFiber(node); - node = node.return; - } while (node); + var lanes = noLongerPendingLanes; - return info; - } catch (x) { - return "\nError generating stack: " + x.message + "\n" + x.stack; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } } +function markRootEntangled(root, entangledLanes) { + root.entangledLanes |= entangledLanes; + var entanglements = root.entanglements; + var lanes = entangledLanes; -var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; -var current = null; -var isRendering = false; -function getCurrentFiberOwnerNameInDevOrNull() { - { - if (current === null) { - return null; - } - - var owner = current._debugOwner; - - if (owner !== null && typeof owner !== "undefined") { - return getComponentName(owner.type); - } + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] |= entangledLanes; + lanes &= ~lane; } - - return null; } +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 -function getCurrentFiberStackInDev() { - { - if (current === null) { - return ""; - } // Safe because if current fiber exists, we are reconciling, - // and it is guaranteed to be the work-in-progress version. +var log = Math.log; +var LN2 = Math.LN2; - return getStackByFiberInDevAndProd(current); +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } -} -function resetCurrentFiber() { - { - ReactDebugCurrentFrame$1.getCurrentStack = null; - current = null; - isRendering = false; - } -} -function setCurrentFiber(fiber) { - { - ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev; - current = fiber; - isRendering = false; - } -} -function setIsRendering(rendering) { - { - isRendering = rendering; - } -} -function getIsRendering() { - { - return isRendering; - } + return (31 - ((log(lanes) / LN2) | 0)) | 0; } -var ReactStrictModeWarnings = { - recordUnsafeLifecycleWarnings: function(fiber, instance) {}, - flushPendingUnsafeLifecycleWarnings: function() {}, - recordLegacyContextWarning: function(fiber, instance) {}, - flushLegacyContextWarning: function() {}, - discardPendingWarnings: function() {} -}; +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; { - var findStrictRoot = function(fiber) { - var maybeStrictRoot = null; - var node = fiber; - - while (node !== null) { - if (node.mode & StrictLegacyMode) { - maybeStrictRoot = node; - } + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); + } +} - node = node.return; - } +var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. - return maybeStrictRoot; - }; +var ImmediatePriority$1 = 99; +var UserBlockingPriority$1 = 98; +var NormalPriority$1 = 97; +var LowPriority$1 = 96; +var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. - var setToSortedString = function(set) { - var array = []; - set.forEach(function(value) { - array.push(value); - }); - return array.sort().join(", "); - }; +var NoPriority$1 = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. - var pendingComponentWillMountWarnings = []; - var pendingUNSAFE_ComponentWillMountWarnings = []; - var pendingComponentWillReceivePropsWarnings = []; - var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; - var pendingComponentWillUpdateWarnings = []; - var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. +var now = + initialTimeMs$1 < 10000 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority$1; - var didWarnAboutUnsafeLifecycles = new Set(); + case Scheduler_UserBlockingPriority: + return UserBlockingPriority$1; - ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( - fiber, - instance - ) { - // Dedupe strategy: Warn once per component. - if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { - return; - } + case Scheduler_NormalPriority: + return NormalPriority$1; - if ( - typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components. - instance.componentWillMount.__suppressDeprecationWarning !== true - ) { - pendingComponentWillMountWarnings.push(fiber); - } + case Scheduler_LowPriority: + return LowPriority$1; - if ( - fiber.mode & StrictLegacyMode && - typeof instance.UNSAFE_componentWillMount === "function" - ) { - pendingUNSAFE_ComponentWillMountWarnings.push(fiber); - } + case Scheduler_IdlePriority: + return IdlePriority$1; - if ( - typeof instance.componentWillReceiveProps === "function" && - instance.componentWillReceiveProps.__suppressDeprecationWarning !== true - ) { - pendingComponentWillReceivePropsWarnings.push(fiber); + default: { + throw Error("Unknown priority level."); } + } +} - if ( - fiber.mode & StrictLegacyMode && - typeof instance.UNSAFE_componentWillReceiveProps === "function" - ) { - pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); - } +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority$1: + return Scheduler_ImmediatePriority; - if ( - typeof instance.componentWillUpdate === "function" && - instance.componentWillUpdate.__suppressDeprecationWarning !== true - ) { - pendingComponentWillUpdateWarnings.push(fiber); - } + case UserBlockingPriority$1: + return Scheduler_UserBlockingPriority; - if ( - fiber.mode & StrictLegacyMode && - typeof instance.UNSAFE_componentWillUpdate === "function" - ) { - pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); - } - }; + case NormalPriority$1: + return Scheduler_NormalPriority; - ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { - // We do an initial pass to gather component names - var componentWillMountUniqueNames = new Set(); + case LowPriority$1: + return Scheduler_LowPriority; - if (pendingComponentWillMountWarnings.length > 0) { - pendingComponentWillMountWarnings.forEach(function(fiber) { - componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingComponentWillMountWarnings = []; + case IdlePriority$1: + return Scheduler_IdlePriority; + + default: { + throw Error("Unknown priority level."); } + } +} - var UNSAFE_componentWillMountUniqueNames = new Set(); +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. - if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { - pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { - UNSAFE_componentWillMountUniqueNames.add( - getComponentName(fiber.type) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingUNSAFE_ComponentWillMountWarnings = []; - } + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); + } - var componentWillReceivePropsUniqueNames = new Set(); + return fakeCallbackNode; +} +function cancelCallback(callbackNode) { + if (callbackNode !== fakeCallbackNode) { + Scheduler_cancelCallback(callbackNode); + } +} +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } - if (pendingComponentWillReceivePropsWarnings.length > 0) { - pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { - componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingComponentWillReceivePropsWarnings = []; - } + flushSyncCallbackQueueImpl(); +} - var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; - if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { - pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { - UNSAFE_componentWillReceivePropsUniqueNames.add( - getComponentName(fiber.type) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingUNSAFE_ComponentWillReceivePropsWarnings = []; - } + { + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority$1, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; - var componentWillUpdateUniqueNames = new Set(); + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick - if (pendingComponentWillUpdateWarnings.length > 0) { - pendingComponentWillUpdateWarnings.forEach(function(fiber) { - componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingComponentWillUpdateWarnings = []; + throw error; + } finally { + isFlushingSyncQueue = false; + } } + } +} - var UNSAFE_componentWillUpdateUniqueNames = new Set(); +// TODO: this is special because it gets imported during build. +var ReactVersion = "17.0.1-454c2211c"; - if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { - pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { - UNSAFE_componentWillUpdateUniqueNames.add( - getComponentName(fiber.type) || "Component" - ); - didWarnAboutUnsafeLifecycles.add(fiber.type); - }); - pendingUNSAFE_ComponentWillUpdateWarnings = []; - } // Finally, we flush all the warnings - // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' +var NoMode = 0; +var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root +// tag instead - if (UNSAFE_componentWillMountUniqueNames.size > 0) { - var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); +var BlockingMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; +var DebugTracingMode = 16; - error( - "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + - "\nPlease update the following components: %s", - sortedNames - ); - } +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var NoTransition = 0; +function requestCurrentTransition() { + return ReactCurrentBatchConfig.transition; +} - if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { - var _sortedNames = setToSortedString( - UNSAFE_componentWillReceivePropsUniqueNames - ); +/** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ +function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare + ); +} - error( - "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + - "and may indicate bugs in your code. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move data fetching code or side effects to componentDidUpdate.\n" + - "* If you're updating state whenever props change, " + - "refactor your code to use memoization techniques or move it to " + - "static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n" + - "\nPlease update the following components: %s", - _sortedNames - ); - } +var objectIs = typeof Object.is === "function" ? Object.is : is; - if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { - var _sortedNames2 = setToSortedString( - UNSAFE_componentWillUpdateUniqueNames - ); - - error( - "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + - "and may indicate bugs in your code. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move data fetching code or side effects to componentDidUpdate.\n" + - "\nPlease update the following components: %s", - _sortedNames2 - ); - } - - if (componentWillMountUniqueNames.size > 0) { - var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); +var hasOwnProperty = Object.prototype.hasOwnProperty; +/** + * Performs equality by iterating through keys on an object and returning false + * when any key has values which are not strictly equal between the arguments. + * Returns true when the values of all keys are strictly equal. + */ - warn( - "componentWillMount has been renamed, and is not recommended for use. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + - "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + - "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + - "To rename all deprecated lifecycles to their new names, you can run " + - "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + - "\nPlease update the following components: %s", - _sortedNames3 - ); - } +function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) { + return true; + } - if (componentWillReceivePropsUniqueNames.size > 0) { - var _sortedNames4 = setToSortedString( - componentWillReceivePropsUniqueNames - ); + if ( + typeof objA !== "object" || + objA === null || + typeof objB !== "object" || + objB === null + ) { + return false; + } - warn( - "componentWillReceiveProps has been renamed, and is not recommended for use. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move data fetching code or side effects to componentDidUpdate.\n" + - "* If you're updating state whenever props change, refactor your " + - "code to use memoization techniques or move it to " + - "static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n" + - "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + - "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + - "To rename all deprecated lifecycles to their new names, you can run " + - "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + - "\nPlease update the following components: %s", - _sortedNames4 - ); - } + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); - if (componentWillUpdateUniqueNames.size > 0) { - var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); + if (keysA.length !== keysB.length) { + return false; + } // Test for A's keys different from B. - warn( - "componentWillUpdate has been renamed, and is not recommended for use. " + - "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + - "* Move data fetching code or side effects to componentDidUpdate.\n" + - "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + - "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + - "To rename all deprecated lifecycles to their new names, you can run " + - "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + - "\nPlease update the following components: %s", - _sortedNames5 - ); + for (var i = 0; i < keysA.length; i++) { + if ( + !hasOwnProperty.call(objB, keysA[i]) || + !objectIs(objA[keysA[i]], objB[keysA[i]]) + ) { + return false; } - }; - - var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. + } - var didWarnAboutLegacyContext = new Set(); + return true; +} - ReactStrictModeWarnings.recordLegacyContextWarning = function( - fiber, - instance - ) { - var strictRoot = findStrictRoot(fiber); +function describeFiber(fiber) { + var owner = fiber._debugOwner ? fiber._debugOwner.type : null; + var source = fiber._debugSource; - if (strictRoot === null) { - error( - "Expected to find a StrictMode component in a strict mode tree. " + - "This error is likely caused by a bug in React. Please file an issue." - ); + switch (fiber.tag) { + case HostComponent: + return describeBuiltInComponentFrame(fiber.type, source, owner); - return; - } // Dedup strategy: Warn once per component. + case LazyComponent: + return describeBuiltInComponentFrame("Lazy", source, owner); - if (didWarnAboutLegacyContext.has(fiber.type)) { - return; - } + case SuspenseComponent: + return describeBuiltInComponentFrame("Suspense", source, owner); - var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); + case SuspenseListComponent: + return describeBuiltInComponentFrame("SuspenseList", source, owner); - if ( - fiber.type.contextTypes != null || - fiber.type.childContextTypes != null || - (instance !== null && typeof instance.getChildContext === "function") - ) { - if (warningsForRoot === undefined) { - warningsForRoot = []; - pendingLegacyContextWarning.set(strictRoot, warningsForRoot); - } + case FunctionComponent: + case IndeterminateComponent: + case SimpleMemoComponent: + return describeFunctionComponentFrame(fiber.type, source, owner); - warningsForRoot.push(fiber); - } - }; + case ForwardRef: + return describeFunctionComponentFrame(fiber.type.render, source, owner); - ReactStrictModeWarnings.flushLegacyContextWarning = function() { - pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { - if (fiberArray.length === 0) { - return; - } + case ClassComponent: + return describeClassComponentFrame(fiber.type, source, owner); - var firstFiber = fiberArray[0]; - var uniqueNames = new Set(); - fiberArray.forEach(function(fiber) { - uniqueNames.add(getComponentName(fiber.type) || "Component"); - didWarnAboutLegacyContext.add(fiber.type); - }); - var sortedNames = setToSortedString(uniqueNames); + default: + return ""; + } +} - try { - setCurrentFiber(firstFiber); +function getStackByFiberInDevAndProd(workInProgress) { + try { + var info = ""; + var node = workInProgress; - error( - "Legacy context API has been detected within a strict-mode tree." + - "\n\nThe old API will be supported in all 16.x releases, but applications " + - "using it should migrate to the new version." + - "\n\nPlease update the following components: %s" + - "\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context", - sortedNames - ); - } finally { - resetCurrentFiber(); - } - }); - }; + do { + info += describeFiber(node); + node = node.return; + } while (node); - ReactStrictModeWarnings.discardPendingWarnings = function() { - pendingComponentWillMountWarnings = []; - pendingUNSAFE_ComponentWillMountWarnings = []; - pendingComponentWillReceivePropsWarnings = []; - pendingUNSAFE_ComponentWillReceivePropsWarnings = []; - pendingComponentWillUpdateWarnings = []; - pendingUNSAFE_ComponentWillUpdateWarnings = []; - pendingLegacyContextWarning = new Map(); - }; + return info; + } catch (x) { + return "\nError generating stack: " + x.message + "\n" + x.stack; + } } -function resolveDefaultProps(Component, baseProps) { - if (Component && Component.defaultProps) { - // Resolve default props. Taken from ReactElement - var props = Object.assign({}, baseProps); - var defaultProps = Component.defaultProps; - - for (var propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } +var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; +var current = null; +var isRendering = false; +function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; } - return props; + var owner = current._debugOwner; + + if (owner !== null && typeof owner !== "undefined") { + return getComponentName(owner.type); + } } - return baseProps; + return null; } -// Max 31 bit integer. The max integer size in V8 for 32-bit systems. -// Math.pow(2, 30) - 1 -// 0b111111111111111111111111111111 -var MAX_SIGNED_31_BIT_INT = 1073741823; - -var valueCursor = createCursor(null); -var rendererSigil; +function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; + } // Safe because if current fiber exists, we are reconciling, + // and it is guaranteed to be the work-in-progress version. -{ - // Use this to detect multiple renderers using the same context - rendererSigil = {}; + return getStackByFiberInDevAndProd(current); + } } -var currentlyRenderingFiber = null; -var lastContextDependency = null; -var lastContextWithAllBitsObserved = null; -var isDisallowedContextReadInDEV = false; -function resetContextDependencies() { - // This is called right before React yields execution, to ensure `readContext` - // cannot be called outside the render phase. - currentlyRenderingFiber = null; - lastContextDependency = null; - lastContextWithAllBitsObserved = null; - +function resetCurrentFiber() { { - isDisallowedContextReadInDEV = false; + ReactDebugCurrentFrame$1.getCurrentStack = null; + current = null; + isRendering = false; } } -function enterDisallowedContextReadInDEV() { +function setCurrentFiber(fiber) { { - isDisallowedContextReadInDEV = true; + ReactDebugCurrentFrame$1.getCurrentStack = getCurrentFiberStackInDev; + current = fiber; + isRendering = false; } } -function exitDisallowedContextReadInDEV() { +function setIsRendering(rendering) { { - isDisallowedContextReadInDEV = false; + isRendering = rendering; } } -function pushProvider(providerFiber, context, nextValue) { +function getIsRendering() { { - push(valueCursor, context._currentValue2, providerFiber); - context._currentValue2 = nextValue; - - { - if ( - context._currentRenderer2 !== undefined && - context._currentRenderer2 !== null && - context._currentRenderer2 !== rendererSigil - ) { - error( - "Detected multiple renderers concurrently rendering the " + - "same context provider. This is currently unsupported." - ); - } - - context._currentRenderer2 = rendererSigil; - } + return isRendering; } } -function popProvider(context, providerFiber) { - var currentValue = valueCursor.current; - pop(valueCursor, providerFiber); - { - context._currentValue2 = currentValue; - } -} -function calculateChangedBits(context, newValue, oldValue) { - if (objectIs(oldValue, newValue)) { - // No change - return 0; - } else { - var changedBits = - typeof context._calculateChangedBits === "function" - ? context._calculateChangedBits(oldValue, newValue) - : MAX_SIGNED_31_BIT_INT; +var ReactStrictModeWarnings = { + recordUnsafeLifecycleWarnings: function(fiber, instance) {}, + flushPendingUnsafeLifecycleWarnings: function() {}, + recordLegacyContextWarning: function(fiber, instance) {}, + flushLegacyContextWarning: function() {}, + discardPendingWarnings: function() {} +}; - { - if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { - error( - "calculateChangedBits: Expected the return value to be a " + - "31-bit integer. Instead received: %s", - changedBits - ); +{ + var findStrictRoot = function(fiber) { + var maybeStrictRoot = null; + var node = fiber; + + while (node !== null) { + if (node.mode & StrictMode) { + maybeStrictRoot = node; } + + node = node.return; } - return changedBits | 0; - } -} -function scheduleWorkOnParentPath(parent, renderLanes) { - // Update the child lanes of all the ancestors, including the alternates. - var node = parent; + return maybeStrictRoot; + }; - while (node !== null) { - var alternate = node.alternate; + var setToSortedString = function(set) { + var array = []; + set.forEach(function(value) { + array.push(value); + }); + return array.sort().join(", "); + }; - if (!isSubsetOfLanes(node.childLanes, renderLanes)) { - node.childLanes = mergeLanes(node.childLanes, renderLanes); + var pendingComponentWillMountWarnings = []; + var pendingUNSAFE_ComponentWillMountWarnings = []; + var pendingComponentWillReceivePropsWarnings = []; + var pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + var pendingComponentWillUpdateWarnings = []; + var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about. - if (alternate !== null) { - alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); - } - } else if ( - alternate !== null && - !isSubsetOfLanes(alternate.childLanes, renderLanes) - ) { - alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); - } else { - // Neither alternate was updated, which means the rest of the - // ancestor path already has sufficient priority. - break; + var didWarnAboutUnsafeLifecycles = new Set(); + + ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function( + fiber, + instance + ) { + // Dedup strategy: Warn once per component. + if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { + return; } - node = node.return; - } -} -function propagateContextChange( - workInProgress, - context, - changedBits, - renderLanes -) { - var fiber = workInProgress.child; + if ( + typeof instance.componentWillMount === "function" && // Don't warn about react-lifecycles-compat polyfilled components. + instance.componentWillMount.__suppressDeprecationWarning !== true + ) { + pendingComponentWillMountWarnings.push(fiber); + } - if (fiber !== null) { - // Set the return pointer of the child to the work-in-progress fiber. - fiber.return = workInProgress; - } + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillMount === "function" + ) { + pendingUNSAFE_ComponentWillMountWarnings.push(fiber); + } - while (fiber !== null) { - var nextFiber = void 0; // Visit this fiber. + if ( + typeof instance.componentWillReceiveProps === "function" && + instance.componentWillReceiveProps.__suppressDeprecationWarning !== true + ) { + pendingComponentWillReceivePropsWarnings.push(fiber); + } - var list = fiber.dependencies; + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillReceiveProps === "function" + ) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); + } - if (list !== null) { - nextFiber = fiber.child; - var dependency = list.firstContext; + if ( + typeof instance.componentWillUpdate === "function" && + instance.componentWillUpdate.__suppressDeprecationWarning !== true + ) { + pendingComponentWillUpdateWarnings.push(fiber); + } - while (dependency !== null) { - // Check if the context matches. - if ( - dependency.context === context && - (dependency.observedBits & changedBits) !== 0 - ) { - // Match! Schedule an update on this fiber. - if (fiber.tag === ClassComponent) { - // Schedule a force update on the work-in-progress. - var lane = pickArbitraryLane(renderLanes); - var update = createUpdate(NoTimestamp, lane); - update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the - // update to the current fiber, too, which means it will persist even if - // this render is thrown away. Since it's a race condition, not sure it's - // worth fixing. - // Inlined `enqueueUpdate` to remove interleaved update check + if ( + fiber.mode & StrictMode && + typeof instance.UNSAFE_componentWillUpdate === "function" + ) { + pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); + } + }; - var updateQueue = fiber.updateQueue; + ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function() { + // We do an initial pass to gather component names + var componentWillMountUniqueNames = new Set(); - if (updateQueue === null); - else { - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; + if (pendingComponentWillMountWarnings.length > 0) { + pendingComponentWillMountWarnings.forEach(function(fiber) { + componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillMountWarnings = []; + } - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } + var UNSAFE_componentWillMountUniqueNames = new Set(); - sharedQueue.pending = update; - } - } + if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) { + pendingUNSAFE_ComponentWillMountWarnings.forEach(function(fiber) { + UNSAFE_componentWillMountUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillMountWarnings = []; + } - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + var componentWillReceivePropsUniqueNames = new Set(); - if (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); - } + if (pendingComponentWillReceivePropsWarnings.length > 0) { + pendingComponentWillReceivePropsWarnings.forEach(function(fiber) { + componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillReceivePropsWarnings = []; + } - scheduleWorkOnParentPath(fiber.return, renderLanes); // Mark the updated lanes on the list, too. + var UNSAFE_componentWillReceivePropsUniqueNames = new Set(); - list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the - // dependency list. + if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) { + pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function(fiber) { + UNSAFE_componentWillReceivePropsUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + } - break; - } + var componentWillUpdateUniqueNames = new Set(); - dependency = dependency.next; - } - } else if (fiber.tag === ContextProvider) { - // Don't scan deeper if this is a matching provider - nextFiber = fiber.type === workInProgress.type ? null : fiber.child; - } else { - // Traverse down. - nextFiber = fiber.child; + if (pendingComponentWillUpdateWarnings.length > 0) { + pendingComponentWillUpdateWarnings.forEach(function(fiber) { + componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingComponentWillUpdateWarnings = []; } - if (nextFiber !== null) { - // Set the return pointer of the child to the work-in-progress fiber. - nextFiber.return = fiber; - } else { - // No child. Traverse to next sibling. - nextFiber = fiber; - - while (nextFiber !== null) { - if (nextFiber === workInProgress) { - // We're back to the root of this subtree. Exit. - nextFiber = null; - break; - } + var UNSAFE_componentWillUpdateUniqueNames = new Set(); - var sibling = nextFiber.sibling; + if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) { + pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function(fiber) { + UNSAFE_componentWillUpdateUniqueNames.add( + getComponentName(fiber.type) || "Component" + ); + didWarnAboutUnsafeLifecycles.add(fiber.type); + }); + pendingUNSAFE_ComponentWillUpdateWarnings = []; + } // Finally, we flush all the warnings + // UNSAFE_ ones before the deprecated ones, since they'll be 'louder' - if (sibling !== null) { - // Set the return pointer of the sibling to the work-in-progress fiber. - sibling.return = nextFiber.return; - nextFiber = sibling; - break; - } // No more siblings. Traverse up. + if (UNSAFE_componentWillMountUniqueNames.size > 0) { + var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames); - nextFiber = nextFiber.return; - } + error( + "Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "\nPlease update the following components: %s", + sortedNames + ); } - fiber = nextFiber; - } -} -function prepareToReadContext(workInProgress, renderLanes) { - currentlyRenderingFiber = workInProgress; - lastContextDependency = null; - lastContextWithAllBitsObserved = null; - var dependencies = workInProgress.dependencies; + if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames = setToSortedString( + UNSAFE_componentWillReceivePropsUniqueNames + ); - if (dependencies !== null) { - var firstContext = dependencies.firstContext; + error( + "Using UNSAFE_componentWillReceiveProps in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, " + + "refactor your code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n" + + "\nPlease update the following components: %s", + _sortedNames + ); + } - if (firstContext !== null) { - if (includesSomeLane(dependencies.lanes, renderLanes)) { - // Context list has a pending update. Mark that this fiber performed work. - markWorkInProgressReceivedUpdate(); - } // Reset the work-in-progress list + if (UNSAFE_componentWillUpdateUniqueNames.size > 0) { + var _sortedNames2 = setToSortedString( + UNSAFE_componentWillUpdateUniqueNames + ); - dependencies.firstContext = null; - } - } -} -function readContext(context, observedBits) { - { - // This warning would fire if you read context inside a Hook like useMemo. - // Unlike the class check below, it's not enforced in production for perf. - if (isDisallowedContextReadInDEV) { error( - "Context can only be read while React is rendering. " + - "In classes, you can read it in the render method or getDerivedStateFromProps. " + - "In function components, you can read it directly in the function body, but not " + - "inside Hooks like useReducer() or useMemo()." + "Using UNSAFE_componentWillUpdate in strict mode is not recommended " + + "and may indicate bugs in your code. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "\nPlease update the following components: %s", + _sortedNames2 ); } - } - if (lastContextWithAllBitsObserved === context); - else if (observedBits === false || observedBits === 0); - else { - var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. + if (componentWillMountUniqueNames.size > 0) { + var _sortedNames3 = setToSortedString(componentWillMountUniqueNames); - if ( - typeof observedBits !== "number" || - observedBits === MAX_SIGNED_31_BIT_INT - ) { - // Observe all updates. - lastContextWithAllBitsObserved = context; - resolvedObservedBits = MAX_SIGNED_31_BIT_INT; - } else { - resolvedObservedBits = observedBits; + warn( + "componentWillMount has been renamed, and is not recommended for use. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move code with side effects to componentDidMount, and set initial state in the constructor.\n" + + "* Rename componentWillMount to UNSAFE_componentWillMount to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames3 + ); } - var contextItem = { - context: context, - observedBits: resolvedObservedBits, - next: null - }; - - if (lastContextDependency === null) { - if (!(currentlyRenderingFiber !== null)) { - throw Error( - "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." - ); - } // This is the first dependency for this component. Create a new list. + if (componentWillReceivePropsUniqueNames.size > 0) { + var _sortedNames4 = setToSortedString( + componentWillReceivePropsUniqueNames + ); - lastContextDependency = contextItem; - currentlyRenderingFiber.dependencies = { - lanes: NoLanes, - firstContext: contextItem, - responders: null - }; - } else { - // Append a new context item. - lastContextDependency = lastContextDependency.next = contextItem; + warn( + "componentWillReceiveProps has been renamed, and is not recommended for use. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* If you're updating state whenever props change, refactor your " + + "code to use memoization techniques or move it to " + + "static getDerivedStateFromProps. Learn more at: https://reactjs.org/link/derived-state\n" + + "* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames4 + ); } - } - - return context._currentValue2; -} -// An array of all update queues that received updates during the current -// render. When this render exits, either because it finishes or because it is -// interrupted, the interleaved updates will be transfered onto the main part -// of the queue. -var interleavedQueues = null; -function pushInterleavedQueue(queue) { - if (interleavedQueues === null) { - interleavedQueues = [queue]; - } else { - interleavedQueues.push(queue); - } -} -function enqueueInterleavedUpdates() { - // Transfer the interleaved updates onto the main queue. Each queue has a - // `pending` field and an `interleaved` field. When they are not null, they - // point to the last node in a circular linked list. We need to append the - // interleaved list to the end of the pending list by joining them into a - // single, circular list. - if (interleavedQueues !== null) { - for (var i = 0; i < interleavedQueues.length; i++) { - var queue = interleavedQueues[i]; - var lastInterleavedUpdate = queue.interleaved; - - if (lastInterleavedUpdate !== null) { - queue.interleaved = null; - var firstInterleavedUpdate = lastInterleavedUpdate.next; - var lastPendingUpdate = queue.pending; - - if (lastPendingUpdate !== null) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = firstInterleavedUpdate; - lastInterleavedUpdate.next = firstPendingUpdate; - } + if (componentWillUpdateUniqueNames.size > 0) { + var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames); - queue.pending = lastInterleavedUpdate; - } + warn( + "componentWillUpdate has been renamed, and is not recommended for use. " + + "See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n" + + "* Move data fetching code or side effects to componentDidUpdate.\n" + + "* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress " + + "this warning in non-strict mode. In React 18.x, only the UNSAFE_ name will work. " + + "To rename all deprecated lifecycles to their new names, you can run " + + "`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n" + + "\nPlease update the following components: %s", + _sortedNames5 + ); } + }; - interleavedQueues = null; - } -} + var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about. -var UpdateState = 0; -var ReplaceState = 1; -var ForceUpdate = 2; -var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. -// It should only be read right after calling `processUpdateQueue`, via -// `checkHasForceUpdateAfterProcessing`. + var didWarnAboutLegacyContext = new Set(); -var hasForceUpdate = false; -var didWarnUpdateInsideUpdate; -var currentlyProcessingQueue; + ReactStrictModeWarnings.recordLegacyContextWarning = function( + fiber, + instance + ) { + var strictRoot = findStrictRoot(fiber); -{ - didWarnUpdateInsideUpdate = false; - currentlyProcessingQueue = null; -} + if (strictRoot === null) { + error( + "Expected to find a StrictMode component in a strict mode tree. " + + "This error is likely caused by a bug in React. Please file an issue." + ); -function initializeUpdateQueue(fiber) { - var queue = { - baseState: fiber.memoizedState, - firstBaseUpdate: null, - lastBaseUpdate: null, - shared: { - pending: null, - interleaved: null, - lanes: NoLanes - }, - effects: null - }; - fiber.updateQueue = queue; -} -function cloneUpdateQueue(current, workInProgress) { - // Clone the update queue from current. Unless it's already a clone. - var queue = workInProgress.updateQueue; - var currentQueue = current.updateQueue; + return; + } // Dedup strategy: Warn once per component. - if (queue === currentQueue) { - var clone = { - baseState: currentQueue.baseState, - firstBaseUpdate: currentQueue.firstBaseUpdate, - lastBaseUpdate: currentQueue.lastBaseUpdate, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = clone; - } -} -function createUpdate(eventTime, lane) { - var update = { - eventTime: eventTime, - lane: lane, - tag: UpdateState, - payload: null, - callback: null, - next: null - }; - return update; -} -function enqueueUpdate(fiber, update, lane) { - var updateQueue = fiber.updateQueue; + if (didWarnAboutLegacyContext.has(fiber.type)) { + return; + } - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; - } + var warningsForRoot = pendingLegacyContextWarning.get(strictRoot); - var sharedQueue = updateQueue.shared; + if ( + fiber.type.contextTypes != null || + fiber.type.childContextTypes != null || + (instance !== null && typeof instance.getChildContext === "function") + ) { + if (warningsForRoot === undefined) { + warningsForRoot = []; + pendingLegacyContextWarning.set(strictRoot, warningsForRoot); + } - if (isInterleavedUpdate(fiber)) { - var interleaved = sharedQueue.interleaved; + warningsForRoot.push(fiber); + } + }; - if (interleaved === null) { - // This is the first update. Create a circular list. - update.next = update; // At the end of the current render, this queue's interleaved updates will - // be transfered to the pending queue. + ReactStrictModeWarnings.flushLegacyContextWarning = function() { + pendingLegacyContextWarning.forEach(function(fiberArray, strictRoot) { + if (fiberArray.length === 0) { + return; + } - pushInterleavedQueue(sharedQueue); - } else { - update.next = interleaved.next; - interleaved.next = update; - } + var firstFiber = fiberArray[0]; + var uniqueNames = new Set(); + fiberArray.forEach(function(fiber) { + uniqueNames.add(getComponentName(fiber.type) || "Component"); + didWarnAboutLegacyContext.add(fiber.type); + }); + var sortedNames = setToSortedString(uniqueNames); - sharedQueue.interleaved = update; - } else { - var pending = sharedQueue.pending; + try { + setCurrentFiber(firstFiber); - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } + error( + "Legacy context API has been detected within a strict-mode tree." + + "\n\nThe old API will be supported in all 16.x releases, but applications " + + "using it should migrate to the new version." + + "\n\nPlease update the following components: %s" + + "\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context", + sortedNames + ); + } finally { + resetCurrentFiber(); + } + }); + }; - sharedQueue.pending = update; - } + ReactStrictModeWarnings.discardPendingWarnings = function() { + pendingComponentWillMountWarnings = []; + pendingUNSAFE_ComponentWillMountWarnings = []; + pendingComponentWillReceivePropsWarnings = []; + pendingUNSAFE_ComponentWillReceivePropsWarnings = []; + pendingComponentWillUpdateWarnings = []; + pendingUNSAFE_ComponentWillUpdateWarnings = []; + pendingLegacyContextWarning = new Map(); + }; +} - { - if ( - currentlyProcessingQueue === sharedQueue && - !didWarnUpdateInsideUpdate - ) { - error( - "An update (setState, replaceState, or forceUpdate) was scheduled " + - "from inside an update function. Update functions should be pure, " + - "with zero side-effects. Consider using componentDidUpdate or a " + - "callback." - ); +function resolveDefaultProps(Component, baseProps) { + if (Component && Component.defaultProps) { + // Resolve default props. Taken from ReactElement + var props = Object.assign({}, baseProps); + var defaultProps = Component.defaultProps; - didWarnUpdateInsideUpdate = true; + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } } - } -} -function entangleTransitions(root, fiber, lane) { - var updateQueue = fiber.updateQueue; - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; + return props; } - var sharedQueue = updateQueue.shared; + return baseProps; +} + +// Max 31 bit integer. The max integer size in V8 for 32-bit systems. +// Math.pow(2, 30) - 1 +// 0b111111111111111111111111111111 +var MAX_SIGNED_31_BIT_INT = 1073741823; - if (isTransitionLane(lane)) { - var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must - // have finished. We can remove them from the shared queue, which represents - // a superset of the actually pending lanes. In some cases we may entangle - // more than we need to, but that's OK. In fact it's worse if we *don't* - // entangle when we should. +var valueCursor = createCursor(null); +var rendererSigil; - queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. +{ + // Use this to detect multiple renderers using the same context + rendererSigil = {}; +} - var newQueueLanes = mergeLanes(queueLanes, lane); - sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if - // the lane finished since the last time we entangled it. So we need to - // entangle it again, just to be sure. +var currentlyRenderingFiber = null; +var lastContextDependency = null; +var lastContextWithAllBitsObserved = null; +var isDisallowedContextReadInDEV = false; +function resetContextDependencies() { + // This is called right before React yields execution, to ensure `readContext` + // cannot be called outside the render phase. + currentlyRenderingFiber = null; + lastContextDependency = null; + lastContextWithAllBitsObserved = null; - markRootEntangled(root, newQueueLanes); + { + isDisallowedContextReadInDEV = false; } } -function enqueueCapturedUpdate(workInProgress, capturedUpdate) { - // Captured updates are updates that are thrown by a child during the render - // phase. They should be discarded if the render is aborted. Therefore, - // we should only put them on the work-in-progress queue, not the current one. - var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. +function enterDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = true; + } +} +function exitDisallowedContextReadInDEV() { + { + isDisallowedContextReadInDEV = false; + } +} +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; - var current = workInProgress.alternate; + { + push(valueCursor, context._currentValue2, providerFiber); + context._currentValue2 = nextValue; - if (current !== null) { - var currentQueue = current.updateQueue; + { + if ( + context._currentRenderer2 !== undefined && + context._currentRenderer2 !== null && + context._currentRenderer2 !== rendererSigil + ) { + error( + "Detected multiple renderers concurrently rendering the " + + "same context provider. This is currently unsupported." + ); + } - if (queue === currentQueue) { - // The work-in-progress queue is the same as current. This happens when - // we bail out on a parent fiber that then captures an error thrown by - // a child. Since we want to append the update only to the work-in - // -progress queue, we need to clone the updates. We usually clone during - // processUpdateQueue, but that didn't happen in this case because we - // skipped over the parent when we bailed out. - var newFirst = null; - var newLast = null; - var firstBaseUpdate = queue.firstBaseUpdate; + context._currentRenderer2 = rendererSigil; + } + } +} +function popProvider(providerFiber) { + var currentValue = valueCursor.current; + pop(valueCursor, providerFiber); + var context = providerFiber.type._context; - if (firstBaseUpdate !== null) { - // Loop through the updates and clone them. - var update = firstBaseUpdate; + { + context._currentValue2 = currentValue; + } +} +function calculateChangedBits(context, newValue, oldValue) { + if (objectIs(oldValue, newValue)) { + // No change + return 0; + } else { + var changedBits = + typeof context._calculateChangedBits === "function" + ? context._calculateChangedBits(oldValue, newValue) + : MAX_SIGNED_31_BIT_INT; - do { - var clone = { - eventTime: update.eventTime, - lane: update.lane, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + { + if ((changedBits & MAX_SIGNED_31_BIT_INT) !== changedBits) { + error( + "calculateChangedBits: Expected the return value to be a " + + "31-bit integer. Instead received: %s", + changedBits + ); + } + } - if (newLast === null) { - newFirst = newLast = clone; - } else { - newLast.next = clone; - newLast = clone; - } + return changedBits | 0; + } +} +function scheduleWorkOnParentPath(parent, renderLanes) { + // Update the child lanes of all the ancestors, including the alternates. + var node = parent; - update = update.next; - } while (update !== null); // Append the captured update the end of the cloned list. + while (node !== null) { + var alternate = node.alternate; - if (newLast === null) { - newFirst = newLast = capturedUpdate; - } else { - newLast.next = capturedUpdate; - newLast = capturedUpdate; - } - } else { - // There are no base updates. - newFirst = newLast = capturedUpdate; - } + if (!isSubsetOfLanes(node.childLanes, renderLanes)) { + node.childLanes = mergeLanes(node.childLanes, renderLanes); - queue = { - baseState: currentQueue.baseState, - firstBaseUpdate: newFirst, - lastBaseUpdate: newLast, - shared: currentQueue.shared, - effects: currentQueue.effects - }; - workInProgress.updateQueue = queue; - return; + if (alternate !== null) { + alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + } + } else if ( + alternate !== null && + !isSubsetOfLanes(alternate.childLanes, renderLanes) + ) { + alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes); + } else { + // Neither alternate was updated, which means the rest of the + // ancestor path already has sufficient priority. + break; } - } // Append the update to the end of the list. - - var lastBaseUpdate = queue.lastBaseUpdate; - if (lastBaseUpdate === null) { - queue.firstBaseUpdate = capturedUpdate; - } else { - lastBaseUpdate.next = capturedUpdate; + node = node.return; } - - queue.lastBaseUpdate = capturedUpdate; } - -function getStateFromUpdate( +function propagateContextChange( workInProgress, - queue, - update, - prevState, - nextProps, - instance + context, + changedBits, + renderLanes ) { - switch (update.tag) { - case ReplaceState: { - var payload = update.payload; + var fiber = workInProgress.child; - if (typeof payload === "function") { - // Updater function - { - enterDisallowedContextReadInDEV(); - } + if (fiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + fiber.return = workInProgress; + } - var nextState = payload.call(instance, prevState, nextProps); + while (fiber !== null) { + var nextFiber = void 0; // Visit this fiber. - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + var list = fiber.dependencies; - try { - payload.call(instance, prevState, nextProps); - } finally { - reenableLogs(); - } - } + if (list !== null) { + nextFiber = fiber.child; + var dependency = list.firstContext; - exitDisallowedContextReadInDEV(); - } + while (dependency !== null) { + // Check if the context matches. + if ( + dependency.context === context && + (dependency.observedBits & changedBits) !== 0 + ) { + // Match! Schedule an update on this fiber. + if (fiber.tag === ClassComponent) { + // Schedule a force update on the work-in-progress. + var update = createUpdate( + NoTimestamp, + pickArbitraryLane(renderLanes) + ); + update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the + // update to the current fiber, too, which means it will persist even if + // this render is thrown away. Since it's a race condition, not sure it's + // worth fixing. - return nextState; - } // State object + enqueueUpdate(fiber, update); + } - return payload; - } + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - case CaptureUpdate: { - workInProgress.flags = - (workInProgress.flags & ~ShouldCapture) | DidCapture; - } - // Intentional fallthrough + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - case UpdateState: { - var _payload = update.payload; - var partialState; + scheduleWorkOnParentPath(fiber.return, renderLanes); // Mark the updated lanes on the list, too. - if (typeof _payload === "function") { - // Updater function - { - enterDisallowedContextReadInDEV(); - } + list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the + // dependency list. - partialState = _payload.call(instance, prevState, nextProps); + break; + } - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + dependency = dependency.next; + } + } else if (fiber.tag === ContextProvider) { + // Don't scan deeper if this is a matching provider + nextFiber = fiber.type === workInProgress.type ? null : fiber.child; + } else { + // Traverse down. + nextFiber = fiber.child; + } - try { - _payload.call(instance, prevState, nextProps); - } finally { - reenableLogs(); - } - } + if (nextFiber !== null) { + // Set the return pointer of the child to the work-in-progress fiber. + nextFiber.return = fiber; + } else { + // No child. Traverse to next sibling. + nextFiber = fiber; - exitDisallowedContextReadInDEV(); + while (nextFiber !== null) { + if (nextFiber === workInProgress) { + // We're back to the root of this subtree. Exit. + nextFiber = null; + break; } - } else { - // Partial state object - partialState = _payload; - } - if (partialState === null || partialState === undefined) { - // Null and undefined are treated as no-ops. - return prevState; - } // Merge the partial state and the previous state. + var sibling = nextFiber.sibling; - return Object.assign({}, prevState, partialState); - } + if (sibling !== null) { + // Set the return pointer of the sibling to the work-in-progress fiber. + sibling.return = nextFiber.return; + nextFiber = sibling; + break; + } // No more siblings. Traverse up. - case ForceUpdate: { - hasForceUpdate = true; - return prevState; + nextFiber = nextFiber.return; + } } - } - return prevState; + fiber = nextFiber; + } } +function prepareToReadContext(workInProgress, renderLanes) { + currentlyRenderingFiber = workInProgress; + lastContextDependency = null; + lastContextWithAllBitsObserved = null; + var dependencies = workInProgress.dependencies; -function processUpdateQueue(workInProgress, props, instance, renderLanes) { - // This is always non-null on a ClassComponent or HostRoot - var queue = workInProgress.updateQueue; - hasForceUpdate = false; + if (dependencies !== null) { + var firstContext = dependencies.firstContext; + if (firstContext !== null) { + if (includesSomeLane(dependencies.lanes, renderLanes)) { + // Context list has a pending update. Mark that this fiber performed work. + markWorkInProgressReceivedUpdate(); + } // Reset the work-in-progress list + + dependencies.firstContext = null; + } + } +} +function readContext(context, observedBits) { { - currentlyProcessingQueue = queue.shared; + // This warning would fire if you read context inside a Hook like useMemo. + // Unlike the class check below, it's not enforced in production for perf. + if (isDisallowedContextReadInDEV) { + error( + "Context can only be read while React is rendering. " + + "In classes, you can read it in the render method or getDerivedStateFromProps. " + + "In function components, you can read it directly in the function body, but not " + + "inside Hooks like useReducer() or useMemo()." + ); + } } - var firstBaseUpdate = queue.firstBaseUpdate; - var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. + if (lastContextWithAllBitsObserved === context); + else if (observedBits === false || observedBits === 0); + else { + var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types. - var pendingQueue = queue.shared.pending; + if ( + typeof observedBits !== "number" || + observedBits === MAX_SIGNED_31_BIT_INT + ) { + // Observe all updates. + lastContextWithAllBitsObserved = context; + resolvedObservedBits = MAX_SIGNED_31_BIT_INT; + } else { + resolvedObservedBits = observedBits; + } - if (pendingQueue !== null) { - queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first - // and last so that it's non-circular. + var contextItem = { + context: context, + observedBits: resolvedObservedBits, + next: null + }; - var lastPendingUpdate = pendingQueue; - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = null; // Append pending updates to base queue + if (lastContextDependency === null) { + if (!(currentlyRenderingFiber !== null)) { + throw Error( + "Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo()." + ); + } // This is the first dependency for this component. Create a new list. - if (lastBaseUpdate === null) { - firstBaseUpdate = firstPendingUpdate; + lastContextDependency = contextItem; + currentlyRenderingFiber.dependencies = { + lanes: NoLanes, + firstContext: contextItem, + responders: null + }; } else { - lastBaseUpdate.next = firstPendingUpdate; + // Append a new context item. + lastContextDependency = lastContextDependency.next = contextItem; } + } - lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then - // we need to transfer the updates to that queue, too. Because the base - // queue is a singly-linked list with no cycles, we can append to both - // lists and take advantage of structural sharing. - // TODO: Pass `current` as argument - - var current = workInProgress.alternate; - - if (current !== null) { - // This is always non-null on a ClassComponent or HostRoot - var currentQueue = current.updateQueue; - var currentLastBaseUpdate = currentQueue.lastBaseUpdate; + return context._currentValue2; +} - if (currentLastBaseUpdate !== lastBaseUpdate) { - if (currentLastBaseUpdate === null) { - currentQueue.firstBaseUpdate = firstPendingUpdate; - } else { - currentLastBaseUpdate.next = firstPendingUpdate; - } +var UpdateState = 0; +var ReplaceState = 1; +var ForceUpdate = 2; +var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`. +// It should only be read right after calling `processUpdateQueue`, via +// `checkHasForceUpdateAfterProcessing`. - currentQueue.lastBaseUpdate = lastPendingUpdate; - } - } - } // These values may change as we process the queue. +var hasForceUpdate = false; +var didWarnUpdateInsideUpdate; +var currentlyProcessingQueue; - if (firstBaseUpdate !== null) { - // Iterate through the list of updates to compute the result. - var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes - // from the original lanes. +{ + didWarnUpdateInsideUpdate = false; + currentlyProcessingQueue = null; +} - var newLanes = NoLanes; - var newBaseState = null; - var newFirstBaseUpdate = null; - var newLastBaseUpdate = null; - var update = firstBaseUpdate; +function initializeUpdateQueue(fiber) { + var queue = { + baseState: fiber.memoizedState, + firstBaseUpdate: null, + lastBaseUpdate: null, + shared: { + pending: null + }, + effects: null + }; + fiber.updateQueue = queue; +} +function cloneUpdateQueue(current, workInProgress) { + // Clone the update queue from current. Unless it's already a clone. + var queue = workInProgress.updateQueue; + var currentQueue = current.updateQueue; - do { - var updateLane = update.lane; - var updateEventTime = update.eventTime; + if (queue === currentQueue) { + var clone = { + baseState: currentQueue.baseState, + firstBaseUpdate: currentQueue.firstBaseUpdate, + lastBaseUpdate: currentQueue.lastBaseUpdate, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = clone; + } +} +function createUpdate(eventTime, lane) { + var update = { + eventTime: eventTime, + lane: lane, + tag: UpdateState, + payload: null, + callback: null, + next: null + }; + return update; +} +function enqueueUpdate(fiber, update) { + var updateQueue = fiber.updateQueue; - if (!isSubsetOfLanes(renderLanes, updateLane)) { - // Priority is insufficient. Skip this update. If this is the first - // skipped update, the previous update/state is the new base - // update/state. - var clone = { - eventTime: updateEventTime, - lane: updateLane, - tag: update.tag, - payload: update.payload, - callback: update.callback, - next: null - }; + if (updateQueue === null) { + // Only occurs if the fiber has been unmounted. + return; + } - if (newLastBaseUpdate === null) { - newFirstBaseUpdate = newLastBaseUpdate = clone; - newBaseState = newState; - } else { - newLastBaseUpdate = newLastBaseUpdate.next = clone; - } // Update the remaining priority in the queue. + var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - newLanes = mergeLanes(newLanes, updateLane); - } else { - // This update does have sufficient priority. - if (newLastBaseUpdate !== null) { - var _clone = { - eventTime: updateEventTime, - // This update is going to be committed so we never want uncommit - // it. Using NoLane works because 0 is a subset of all bitmasks, so - // this will never be skipped by the check above. - lane: NoLane, + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + sharedQueue.pending = update; + + { + if ( + currentlyProcessingQueue === sharedQueue && + !didWarnUpdateInsideUpdate + ) { + error( + "An update (setState, replaceState, or forceUpdate) was scheduled " + + "from inside an update function. Update functions should be pure, " + + "with zero side-effects. Consider using componentDidUpdate or a " + + "callback." + ); + + didWarnUpdateInsideUpdate = true; + } + } +} +function enqueueCapturedUpdate(workInProgress, capturedUpdate) { + // Captured updates are updates that are thrown by a child during the render + // phase. They should be discarded if the render is aborted. Therefore, + // we should only put them on the work-in-progress queue, not the current one. + var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. + + var current = workInProgress.alternate; + + if (current !== null) { + var currentQueue = current.updateQueue; + + if (queue === currentQueue) { + // The work-in-progress queue is the same as current. This happens when + // we bail out on a parent fiber that then captures an error thrown by + // a child. Since we want to append the update only to the work-in + // -progress queue, we need to clone the updates. We usually clone during + // processUpdateQueue, but that didn't happen in this case because we + // skipped over the parent when we bailed out. + var newFirst = null; + var newLast = null; + var firstBaseUpdate = queue.firstBaseUpdate; + + if (firstBaseUpdate !== null) { + // Loop through the updates and clone them. + var update = firstBaseUpdate; + + do { + var clone = { + eventTime: update.eventTime, + lane: update.lane, tag: update.tag, payload: update.payload, callback: update.callback, next: null }; - newLastBaseUpdate = newLastBaseUpdate.next = _clone; - } // Process this update. - newState = getStateFromUpdate( - workInProgress, - queue, - update, - newState, - props, - instance - ); - var callback = update.callback; - - if (callback !== null) { - workInProgress.flags |= Callback; - var effects = queue.effects; - - if (effects === null) { - queue.effects = [update]; + if (newLast === null) { + newFirst = newLast = clone; } else { - effects.push(update); + newLast.next = clone; + newLast = clone; } - } - } - - update = update.next; - if (update === null) { - pendingQueue = queue.shared.pending; + update = update.next; + } while (update !== null); // Append the captured update the end of the cloned list. - if (pendingQueue === null) { - break; + if (newLast === null) { + newFirst = newLast = capturedUpdate; } else { - // An update was scheduled from inside a reducer. Add the new - // pending updates to the end of the list and keep processing. - var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we - // unravel them when transferring them to the base queue. - - var _firstPendingUpdate = _lastPendingUpdate.next; - _lastPendingUpdate.next = null; - update = _firstPendingUpdate; - queue.lastBaseUpdate = _lastPendingUpdate; - queue.shared.pending = null; + newLast.next = capturedUpdate; + newLast = capturedUpdate; } + } else { + // There are no base updates. + newFirst = newLast = capturedUpdate; } - } while (true); - if (newLastBaseUpdate === null) { - newBaseState = newState; + queue = { + baseState: currentQueue.baseState, + firstBaseUpdate: newFirst, + lastBaseUpdate: newLast, + shared: currentQueue.shared, + effects: currentQueue.effects + }; + workInProgress.updateQueue = queue; + return; } + } // Append the update to the end of the list. - queue.baseState = newBaseState; - queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to - // process them during this render, but we do need to track which lanes - // are remaining. - - var lastInterleaved = queue.shared.interleaved; - - if (lastInterleaved !== null) { - var interleaved = lastInterleaved; - - do { - newLanes = mergeLanes(newLanes, interleaved.lane); - interleaved = interleaved.next; - } while (interleaved !== lastInterleaved); - } else if (firstBaseUpdate === null) { - // `queue.lanes` is used for entangling transitions. We can set it back to - // zero once the queue is empty. - queue.shared.lanes = NoLanes; - } // Set the remaining expiration time to be whatever is remaining in the queue. - // This should be fine because the only two other things that contribute to - // expiration time are props and context. We're already in the middle of the - // begin phase by the time we start processing the queue, so we've already - // dealt with the props. Context in components that specify - // shouldComponentUpdate is tricky; but we'll have to account for - // that regardless. + var lastBaseUpdate = queue.lastBaseUpdate; - markSkippedUpdateLanes(newLanes); - workInProgress.lanes = newLanes; - workInProgress.memoizedState = newState; + if (lastBaseUpdate === null) { + queue.firstBaseUpdate = capturedUpdate; + } else { + lastBaseUpdate.next = capturedUpdate; } - { - currentlyProcessingQueue = null; - } + queue.lastBaseUpdate = capturedUpdate; } -function callCallback(callback, context) { - if (!(typeof callback === "function")) { - throw Error( - "Invalid argument passed as callback. Expected a function. Instead received: " + - callback - ); - } +function getStateFromUpdate( + workInProgress, + queue, + update, + prevState, + nextProps, + instance +) { + switch (update.tag) { + case ReplaceState: { + var payload = update.payload; - callback.call(context); -} + if (typeof payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } -function resetHasForceUpdateBeforeProcessing() { - hasForceUpdate = false; -} -function checkHasForceUpdateAfterProcessing() { - return hasForceUpdate; -} -function commitUpdateQueue(finishedWork, finishedQueue, instance) { - // Commit the effects - var effects = finishedQueue.effects; - finishedQueue.effects = null; + var nextState = payload.call(instance, prevState, nextProps); - if (effects !== null) { - for (var i = 0; i < effects.length; i++) { - var effect = effects[i]; - var callback = effect.callback; + { + if (workInProgress.mode & StrictMode) { + disableLogs(); - if (callback !== null) { - effect.callback = null; - callCallback(callback, instance); - } - } - } -} - -var fakeInternalInstance = {}; -var isArray = Array.isArray; // React.Component uses a shared frozen object by default. -// We'll use it to determine whether we need to initialize legacy refs. + try { + payload.call(instance, prevState, nextProps); + } finally { + reenableLogs(); + } + } -var emptyRefsObject = new React.Component().refs; -var didWarnAboutStateAssignmentForComponent; -var didWarnAboutUninitializedState; -var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; -var didWarnAboutLegacyLifecyclesAndDerivedState; -var didWarnAboutUndefinedDerivedState; -var warnOnUndefinedDerivedState; -var warnOnInvalidCallback; -var didWarnAboutDirectlyAssigningPropsToState; -var didWarnAboutContextTypeAndContextTypes; -var didWarnAboutInvalidateContextType; + exitDisallowedContextReadInDEV(); + } -{ - didWarnAboutStateAssignmentForComponent = new Set(); - didWarnAboutUninitializedState = new Set(); - didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); - didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); - didWarnAboutDirectlyAssigningPropsToState = new Set(); - didWarnAboutUndefinedDerivedState = new Set(); - didWarnAboutContextTypeAndContextTypes = new Set(); - didWarnAboutInvalidateContextType = new Set(); - var didWarnOnInvalidCallback = new Set(); + return nextState; + } // State object - warnOnInvalidCallback = function(callback, callerName) { - if (callback === null || typeof callback === "function") { - return; + return payload; } - var key = callerName + "_" + callback; + case CaptureUpdate: { + workInProgress.flags = + (workInProgress.flags & ~ShouldCapture) | DidCapture; + } + // Intentional fallthrough - if (!didWarnOnInvalidCallback.has(key)) { - didWarnOnInvalidCallback.add(key); + case UpdateState: { + var _payload = update.payload; + var partialState; - error( - "%s(...): Expected the last optional `callback` argument to be a " + - "function. Instead received: %s.", - callerName, - callback - ); - } - }; + if (typeof _payload === "function") { + // Updater function + { + enterDisallowedContextReadInDEV(); + } - warnOnUndefinedDerivedState = function(type, partialState) { - if (partialState === undefined) { - var componentName = getComponentName(type) || "Component"; + partialState = _payload.call(instance, prevState, nextProps); - if (!didWarnAboutUndefinedDerivedState.has(componentName)) { - didWarnAboutUndefinedDerivedState.add(componentName); + { + if (workInProgress.mode & StrictMode) { + disableLogs(); - error( - "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + - "You have returned undefined.", - componentName - ); - } - } - }; // This is so gross but it's at least non-critical and can be removed if - // it causes problems. This is meant to give a nicer error message for - // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, - // ...)) which otherwise throws a "_processChildContext is not a function" - // exception. + try { + _payload.call(instance, prevState, nextProps); + } finally { + reenableLogs(); + } + } - Object.defineProperty(fakeInternalInstance, "_processChildContext", { - enumerable: false, - value: function() { - { - throw Error( - "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." - ); + exitDisallowedContextReadInDEV(); + } + } else { + // Partial state object + partialState = _payload; } - } - }); - Object.freeze(fakeInternalInstance); -} -function applyDerivedStateFromProps( - workInProgress, - ctor, - getDerivedStateFromProps, - nextProps -) { - var prevState = workInProgress.memoizedState; + if (partialState === null || partialState === undefined) { + // Null and undefined are treated as no-ops. + return prevState; + } // Merge the partial state and the previous state. - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + return Object.assign({}, prevState, partialState); + } - try { - // Invoke the function an extra time to help detect side-effects. - getDerivedStateFromProps(nextProps, prevState); - } finally { - reenableLogs(); - } + case ForceUpdate: { + hasForceUpdate = true; + return prevState; } } - var partialState = getDerivedStateFromProps(nextProps, prevState); - - { - warnOnUndefinedDerivedState(ctor, partialState); - } // Merge the partial state and the previous state. + return prevState; +} - var memoizedState = - partialState === null || partialState === undefined - ? prevState - : Object.assign({}, prevState, partialState); - workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the - // base state. +function processUpdateQueue(workInProgress, props, instance, renderLanes) { + // This is always non-null on a ClassComponent or HostRoot + var queue = workInProgress.updateQueue; + hasForceUpdate = false; - if (workInProgress.lanes === NoLanes) { - // Queue is always non-null for classes - var updateQueue = workInProgress.updateQueue; - updateQueue.baseState = memoizedState; + { + currentlyProcessingQueue = queue.shared; } -} -var classComponentUpdater = { - isMounted: isMounted, - enqueueSetState: function(inst, payload, callback) { - var fiber = get(inst); - var eventTime = requestEventTime(); - var lane = requestUpdateLane(fiber); - var update = createUpdate(eventTime, lane); - update.payload = payload; - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "setState"); - } + var firstBaseUpdate = queue.firstBaseUpdate; + var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue. - update.callback = callback; - } + var pendingQueue = queue.shared.pending; - enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + if (pendingQueue !== null) { + queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first + // and last so that it's non-circular. - if (root !== null) { - entangleTransitions(root, fiber, lane); + var lastPendingUpdate = pendingQueue; + var firstPendingUpdate = lastPendingUpdate.next; + lastPendingUpdate.next = null; // Append pending updates to base queue + + if (lastBaseUpdate === null) { + firstBaseUpdate = firstPendingUpdate; + } else { + lastBaseUpdate.next = firstPendingUpdate; } - }, - enqueueReplaceState: function(inst, payload, callback) { - var fiber = get(inst); - var eventTime = requestEventTime(); - var lane = requestUpdateLane(fiber); - var update = createUpdate(eventTime, lane); - update.tag = ReplaceState; - update.payload = payload; - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "replaceState"); - } + lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then + // we need to transfer the updates to that queue, too. Because the base + // queue is a singly-linked list with no cycles, we can append to both + // lists and take advantage of structural sharing. + // TODO: Pass `current` as argument - update.callback = callback; - } + var current = workInProgress.alternate; - enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + if (current !== null) { + // This is always non-null on a ClassComponent or HostRoot + var currentQueue = current.updateQueue; + var currentLastBaseUpdate = currentQueue.lastBaseUpdate; - if (root !== null) { - entangleTransitions(root, fiber, lane); - } - }, - enqueueForceUpdate: function(inst, callback) { - var fiber = get(inst); - var eventTime = requestEventTime(); - var lane = requestUpdateLane(fiber); - var update = createUpdate(eventTime, lane); - update.tag = ForceUpdate; + if (currentLastBaseUpdate !== lastBaseUpdate) { + if (currentLastBaseUpdate === null) { + currentQueue.firstBaseUpdate = firstPendingUpdate; + } else { + currentLastBaseUpdate.next = firstPendingUpdate; + } - if (callback !== undefined && callback !== null) { - { - warnOnInvalidCallback(callback, "forceUpdate"); + currentQueue.lastBaseUpdate = lastPendingUpdate; } - - update.callback = callback; } + } // These values may change as we process the queue. - enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); + if (firstBaseUpdate !== null) { + // Iterate through the list of updates to compute the result. + var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes + // from the original lanes. - if (root !== null) { - entangleTransitions(root, fiber, lane); - } - } -}; + var newLanes = NoLanes; + var newBaseState = null; + var newFirstBaseUpdate = null; + var newLastBaseUpdate = null; + var update = firstBaseUpdate; -function checkShouldComponentUpdate( - workInProgress, - ctor, - oldProps, - newProps, - oldState, - newState, - nextContext -) { - var instance = workInProgress.stateNode; + do { + var updateLane = update.lane; + var updateEventTime = update.eventTime; - if (typeof instance.shouldComponentUpdate === "function") { - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + if (!isSubsetOfLanes(renderLanes, updateLane)) { + // Priority is insufficient. Skip this update. If this is the first + // skipped update, the previous update/state is the new base + // update/state. + var clone = { + eventTime: updateEventTime, + lane: updateLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; - try { - // Invoke the function an extra time to help detect side-effects. - instance.shouldComponentUpdate(newProps, newState, nextContext); - } finally { - reenableLogs(); + if (newLastBaseUpdate === null) { + newFirstBaseUpdate = newLastBaseUpdate = clone; + newBaseState = newState; + } else { + newLastBaseUpdate = newLastBaseUpdate.next = clone; + } // Update the remaining priority in the queue. + + newLanes = mergeLanes(newLanes, updateLane); + } else { + // This update does have sufficient priority. + if (newLastBaseUpdate !== null) { + var _clone = { + eventTime: updateEventTime, + // This update is going to be committed so we never want uncommit + // it. Using NoLane works because 0 is a subset of all bitmasks, so + // this will never be skipped by the check above. + lane: NoLane, + tag: update.tag, + payload: update.payload, + callback: update.callback, + next: null + }; + newLastBaseUpdate = newLastBaseUpdate.next = _clone; + } // Process this update. + + newState = getStateFromUpdate( + workInProgress, + queue, + update, + newState, + props, + instance + ); + var callback = update.callback; + + if (callback !== null) { + workInProgress.flags |= Callback; + var effects = queue.effects; + + if (effects === null) { + queue.effects = [update]; + } else { + effects.push(update); + } } } - } - var shouldUpdate = instance.shouldComponentUpdate( - newProps, - newState, - nextContext - ); + update = update.next; - { - if (shouldUpdate === undefined) { - error( - "%s.shouldComponentUpdate(): Returned undefined instead of a " + - "boolean value. Make sure to return true or false.", - getComponentName(ctor) || "Component" - ); + if (update === null) { + pendingQueue = queue.shared.pending; + + if (pendingQueue === null) { + break; + } else { + // An update was scheduled from inside a reducer. Add the new + // pending updates to the end of the list and keep processing. + var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we + // unravel them when transferring them to the base queue. + + var _firstPendingUpdate = _lastPendingUpdate.next; + _lastPendingUpdate.next = null; + update = _firstPendingUpdate; + queue.lastBaseUpdate = _lastPendingUpdate; + queue.shared.pending = null; + } } + } while (true); + + if (newLastBaseUpdate === null) { + newBaseState = newState; } - return shouldUpdate; + queue.baseState = newBaseState; + queue.firstBaseUpdate = newFirstBaseUpdate; + queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. + // This should be fine because the only two other things that contribute to + // expiration time are props and context. We're already in the middle of the + // begin phase by the time we start processing the queue, so we've already + // dealt with the props. Context in components that specify + // shouldComponentUpdate is tricky; but we'll have to account for + // that regardless. + + markSkippedUpdateLanes(newLanes); + workInProgress.lanes = newLanes; + workInProgress.memoizedState = newState; } - if (ctor.prototype && ctor.prototype.isPureReactComponent) { - return ( - !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + { + currentlyProcessingQueue = null; + } +} + +function callCallback(callback, context) { + if (!(typeof callback === "function")) { + throw Error( + "Invalid argument passed as callback. Expected a function. Instead received: " + + callback ); } - return true; + callback.call(context); } -function checkClassInstance(workInProgress, ctor, newProps) { - var instance = workInProgress.stateNode; +function resetHasForceUpdateBeforeProcessing() { + hasForceUpdate = false; +} +function checkHasForceUpdateAfterProcessing() { + return hasForceUpdate; +} +function commitUpdateQueue(finishedWork, finishedQueue, instance) { + // Commit the effects + var effects = finishedQueue.effects; + finishedQueue.effects = null; - { - var name = getComponentName(ctor) || "Component"; - var renderPresent = instance.render; + if (effects !== null) { + for (var i = 0; i < effects.length; i++) { + var effect = effects[i]; + var callback = effect.callback; - if (!renderPresent) { - if (ctor.prototype && typeof ctor.prototype.render === "function") { - error( - "%s(...): No `render` method found on the returned component " + - "instance: did you accidentally return an object from the constructor?", - name - ); - } else { - error( - "%s(...): No `render` method found on the returned component " + - "instance: you may have forgotten to define `render`.", - name - ); + if (callback !== null) { + effect.callback = null; + callCallback(callback, instance); } } + } +} - if ( - instance.getInitialState && - !instance.getInitialState.isReactClassApproved && - !instance.state - ) { - error( - "getInitialState was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Did you mean to define a state property instead?", - name - ); - } +var fakeInternalInstance = {}; +var isArray = Array.isArray; // React.Component uses a shared frozen object by default. +// We'll use it to determine whether we need to initialize legacy refs. - if ( - instance.getDefaultProps && - !instance.getDefaultProps.isReactClassApproved - ) { - error( - "getDefaultProps was defined on %s, a plain JavaScript class. " + - "This is only supported for classes created using React.createClass. " + - "Use a static property to define defaultProps instead.", - name - ); - } +var emptyRefsObject = new React.Component().refs; +var didWarnAboutStateAssignmentForComponent; +var didWarnAboutUninitializedState; +var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate; +var didWarnAboutLegacyLifecyclesAndDerivedState; +var didWarnAboutUndefinedDerivedState; +var warnOnUndefinedDerivedState; +var warnOnInvalidCallback; +var didWarnAboutDirectlyAssigningPropsToState; +var didWarnAboutContextTypeAndContextTypes; +var didWarnAboutInvalidateContextType; - if (instance.propTypes) { - error( - "propTypes was defined as an instance property on %s. Use a static " + - "property to define propTypes instead.", - name - ); +{ + didWarnAboutStateAssignmentForComponent = new Set(); + didWarnAboutUninitializedState = new Set(); + didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set(); + didWarnAboutLegacyLifecyclesAndDerivedState = new Set(); + didWarnAboutDirectlyAssigningPropsToState = new Set(); + didWarnAboutUndefinedDerivedState = new Set(); + didWarnAboutContextTypeAndContextTypes = new Set(); + didWarnAboutInvalidateContextType = new Set(); + var didWarnOnInvalidCallback = new Set(); + + warnOnInvalidCallback = function(callback, callerName) { + if (callback === null || typeof callback === "function") { + return; } - if (instance.contextType) { + var key = callerName + "_" + callback; + + if (!didWarnOnInvalidCallback.has(key)) { + didWarnOnInvalidCallback.add(key); + error( - "contextType was defined as an instance property on %s. Use a static " + - "property to define contextType instead.", - name + "%s(...): Expected the last optional `callback` argument to be a " + + "function. Instead received: %s.", + callerName, + callback ); } + }; + + warnOnUndefinedDerivedState = function(type, partialState) { + if (partialState === undefined) { + var componentName = getComponentName(type) || "Component"; + + if (!didWarnAboutUndefinedDerivedState.has(componentName)) { + didWarnAboutUndefinedDerivedState.add(componentName); - { - if (instance.contextTypes) { error( - "contextTypes was defined as an instance property on %s. Use a static " + - "property to define contextTypes instead.", - name + "%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. " + + "You have returned undefined.", + componentName + ); + } + } + }; // This is so gross but it's at least non-critical and can be removed if + // it causes problems. This is meant to give a nicer error message for + // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component, + // ...)) which otherwise throws a "_processChildContext is not a function" + // exception. + + Object.defineProperty(fakeInternalInstance, "_processChildContext", { + enumerable: false, + value: function() { + { + throw Error( + "_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal)." + ); + } + } + }); + Object.freeze(fakeInternalInstance); +} + +function applyDerivedStateFromProps( + workInProgress, + ctor, + getDerivedStateFromProps, + nextProps +) { + var prevState = workInProgress.memoizedState; + + { + if (workInProgress.mode & StrictMode) { + disableLogs(); + + try { + // Invoke the function an extra time to help detect side-effects. + getDerivedStateFromProps(nextProps, prevState); + } finally { + reenableLogs(); + } + } + } + + var partialState = getDerivedStateFromProps(nextProps, prevState); + + { + warnOnUndefinedDerivedState(ctor, partialState); + } // Merge the partial state and the previous state. + + var memoizedState = + partialState === null || partialState === undefined + ? prevState + : Object.assign({}, prevState, partialState); + workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the + // base state. + + if (workInProgress.lanes === NoLanes) { + // Queue is always non-null for classes + var updateQueue = workInProgress.updateQueue; + updateQueue.baseState = memoizedState; + } +} +var classComponentUpdater = { + isMounted: isMounted, + enqueueSetState: function(inst, payload, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback, "setState"); + } + + update.callback = callback; + } + + enqueueUpdate(fiber, update); + scheduleUpdateOnFiber(fiber, lane, eventTime); + }, + enqueueReplaceState: function(inst, payload, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.tag = ReplaceState; + update.payload = payload; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback, "replaceState"); + } + + update.callback = callback; + } + + enqueueUpdate(fiber, update); + scheduleUpdateOnFiber(fiber, lane, eventTime); + }, + enqueueForceUpdate: function(inst, callback) { + var fiber = get(inst); + var eventTime = requestEventTime(); + var lane = requestUpdateLane(fiber); + var update = createUpdate(eventTime, lane); + update.tag = ForceUpdate; + + if (callback !== undefined && callback !== null) { + { + warnOnInvalidCallback(callback, "forceUpdate"); + } + + update.callback = callback; + } + + enqueueUpdate(fiber, update); + scheduleUpdateOnFiber(fiber, lane, eventTime); + } +}; + +function checkShouldComponentUpdate( + workInProgress, + ctor, + oldProps, + newProps, + oldState, + newState, + nextContext +) { + var instance = workInProgress.stateNode; + + if (typeof instance.shouldComponentUpdate === "function") { + { + if (workInProgress.mode & StrictMode) { + disableLogs(); + + try { + // Invoke the function an extra time to help detect side-effects. + instance.shouldComponentUpdate(newProps, newState, nextContext); + } finally { + reenableLogs(); + } + } + } + + var shouldUpdate = instance.shouldComponentUpdate( + newProps, + newState, + nextContext + ); + + { + if (shouldUpdate === undefined) { + error( + "%s.shouldComponentUpdate(): Returned undefined instead of a " + + "boolean value. Make sure to return true or false.", + getComponentName(ctor) || "Component" + ); + } + } + + return shouldUpdate; + } + + if (ctor.prototype && ctor.prototype.isPureReactComponent) { + return ( + !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) + ); + } + + return true; +} + +function checkClassInstance(workInProgress, ctor, newProps) { + var instance = workInProgress.stateNode; + + { + var name = getComponentName(ctor) || "Component"; + var renderPresent = instance.render; + + if (!renderPresent) { + if (ctor.prototype && typeof ctor.prototype.render === "function") { + error( + "%s(...): No `render` method found on the returned component " + + "instance: did you accidentally return an object from the constructor?", + name + ); + } else { + error( + "%s(...): No `render` method found on the returned component " + + "instance: you may have forgotten to define `render`.", + name + ); + } + } + + if ( + instance.getInitialState && + !instance.getInitialState.isReactClassApproved && + !instance.state + ) { + error( + "getInitialState was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Did you mean to define a state property instead?", + name + ); + } + + if ( + instance.getDefaultProps && + !instance.getDefaultProps.isReactClassApproved + ) { + error( + "getDefaultProps was defined on %s, a plain JavaScript class. " + + "This is only supported for classes created using React.createClass. " + + "Use a static property to define defaultProps instead.", + name + ); + } + + if (instance.propTypes) { + error( + "propTypes was defined as an instance property on %s. Use a static " + + "property to define propTypes instead.", + name + ); + } + + if (instance.contextType) { + error( + "contextType was defined as an instance property on %s. Use a static " + + "property to define contextType instead.", + name + ); + } + + { + if (instance.contextTypes) { + error( + "contextTypes was defined as an instance property on %s. Use a static " + + "property to define contextTypes instead.", + name ); } @@ -7756,7 +7539,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -7969,7 +7752,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -8013,9 +7796,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } } @@ -8077,9 +7858,7 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } return false; @@ -8125,17 +7904,13 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8385,7 +8160,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8487,14 +8262,12 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { - var childString = Object.prototype.toString.call(newChild); - { throw Error( "Objects are not valid as a React child (found: " + - (childString === "[object Object]" + (Object.prototype.toString.call(newChild) === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : childString) + + : newChild) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8517,7 +8290,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} +} // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8527,16 +8300,23 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } + } // Deletions are added in reversed order so we add it to the front. + // At this point, the return fiber's effect list is empty except for + // deletions, so we can just append the deletion to the list. The remaining + // effects aren't added until the complete phase. Once we implement + // resuming, this may not be true. - var deletions = returnFiber.deletions; + var last = returnFiber.lastEffect; - if (deletions === null) { - returnFiber.deletions = [childToDelete]; - returnFiber.flags |= ChildDeletion; + if (last !== null) { + last.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; } else { - deletions.push(childToDelete); + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } + + childToDelete.nextEffect = null; + childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8600,7 +8380,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags |= Placement; + newFiber.flags = Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8608,7 +8388,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags |= Placement; + newFiber.flags = Placement; return lastPlacedIndex; } } @@ -8617,7 +8397,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags |= Placement; + newFiber.flags = Placement; } return newFiber; @@ -8638,26 +8418,10 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - - if (elementType === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - } - if (current !== null) { if ( - current.elementType === elementType || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. - // We need to do this after the Hot Reloading check above, - // because hot reloading has different semantics than prod because - // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + current.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) ) { // Move based on index var existing = useFiber(current, element.props); @@ -8796,6 +8560,16 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { + if (newChild.type === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ); + } + return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -8853,6 +8627,16 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; + if (newChild.type === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + _matchedFiber, + newChild.props.children, + lanes, + newChild.key + ); + } + return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9346,43 +9130,45 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - var elementType = element.type; + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - if (elementType === REACT_FRAGMENT_TYPE) { - if (child.tag === Fragment) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + return existing; } - return existing; + break; } - } else { - if ( - child.elementType === elementType || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. - // We need to do this after the Hot Reloading check above, - // because hot reloading has different semantics than prod because - // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var _existing = useFiber(child, element.props); + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing = useFiber(child, element.props); - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; } - return _existing; + break; } } // Didn't match. @@ -9813,6 +9599,21 @@ function findFirstSuspended(row) { return null; } +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; + var isHydrating = false; function enterHydrationState(fiber) { @@ -9908,12 +9709,6 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. -function getSuspendedCachePool() { - { - return null; - } // We check the cache on the stack first, since that's the one any new Caches -} - var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -10199,20 +9994,7 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last - // render. If this fires, it suggests that we incorrectly reset the static - // flags in some other part of the codebase. This has happened before, for - // example, in the SuspenseList implementation. - - if ( - current !== null && - (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) - ) { - error( - "Internal React error: Expected static flag was missing. Please " + - "notify the React team." - ); - } + hookTypesUpdateIndexDev = -1; } didScheduleRenderPhaseUpdate = false; @@ -10226,13 +10008,8 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the - // complete phase (bubbleProperties). - - { - workInProgress.flags &= ~(Passive | Update); - } - + workInProgress.updateQueue = current.updateQueue; + workInProgress.flags &= ~(Passive | Update); current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10383,8 +10160,6 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10522,28 +10297,6 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; - } // Interleaved updates are stored on a separate queue. We aren't going to - // process them during this render, but we do need to track which lanes - // are remaining. - - var lastInterleaved = queue.interleaved; - - if (lastInterleaved !== null) { - var interleaved = lastInterleaved; - - do { - var interleavedLane = interleaved.lane; - currentlyRenderingFiber$1.lanes = mergeLanes( - currentlyRenderingFiber$1.lanes, - interleavedLane - ); - markSkippedUpdateLanes(interleavedLane); - interleaved = interleaved.next; - } while (interleaved !== lastInterleaved); - } else if (baseQueue === null) { - // `queue.lanes` is used for entangling transitions. We can set it back to - // zero once the queue is empty. - queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10671,48 +10424,11 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During - // the synchronous retry, it will block interleaved mutations, so we should - // get a consistent read. Therefore, the following error should never be - // visible to the user. - // - // If it were to become visible to the user, it suggests one of two things: - // a bug in React, or (more likely), a mutation during the render phase that - // caused the second re-render attempt to be different from the first. - // - // We know it's the second case if the logs are currently disabled. So in - // dev, we can present a more accurate error message. - - { - // eslint-disable-next-line react-internal/no-production-logging - if (console.log.__reactDisabledLog) { - // If the logs are disabled, this is the dev-only double render. This is - // only reachable if there was a mutation during render. Show a helpful - // error message. - // - // Something interesting to note: because we only double render in - // development, this error will never happen during production. This is - // actually true of all errors that occur during a double render, - // because if the first render had thrown, we would have exited the - // begin phase without double rendering. We should consider suppressing - // any error from a double render (with a warning) to more closely match - // the production behavior. - var componentName = getComponentName(currentlyRenderingFiber$1.type); - - { - throw Error( - "A mutable source was mutated while the " + - componentName + - " component was rendering. This is not supported. Move any mutations into event handlers or effects." - ); - } - } - } // We expect this error not to be thrown during the synchronous retry, - // because we blocked interleaved mutations. + markSourceAsDirty(source); { throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } } @@ -10848,8 +10564,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -10897,8 +10611,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -10992,7 +10704,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -11008,19 +10720,15 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { } function mountEffect(create, deps) { - { - return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); - } + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(Passive, Passive$1, create, deps); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - { - return mountEffectImpl(Update, Layout, create, deps); - } + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -11072,15 +10780,12 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - - { - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); - } + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); } function updateImperativeHandle(ref, create, deps) { @@ -11235,15 +10940,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority - ? UserBlockingPriority + priorityLevel < UserBlockingPriority$1 + ? UserBlockingPriority$1 : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11355,7 +11060,19 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; + }; // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11366,47 +11083,7 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; } else { - if (isInterleavedUpdate(fiber)) { - var interleaved = queue.interleaved; - - if (interleaved === null) { - // This is the first update. Create a circular list. - update.next = update; // At the end of the current render, this queue's interleaved updates will - // be transfered to the pending queue. - - pushInterleavedQueue(queue); - } else { - update.next = interleaved.next; - interleaved.next = update; - } - - queue.interleaved = update; - } else { - var _pending = queue.pending; - - if (_pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = _pending.next; - _pending.next = update; - } - - queue.pending = update; - } - if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11451,24 +11128,7 @@ function dispatchAction(fiber, queue, action) { } } - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); - - if (isTransitionLane(lane) && root !== null) { - var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they - // must have finished. We can remove them from the shared queue, which - // represents a superset of the actually pending lanes. In some cases we - // may entangle more than we need to, but that's OK. In fact it's worse if - // we *don't* entangle when we should. - - queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. - - var newQueueLanes = mergeLanes(queueLanes, lane); - queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if - // the lane finished since the last time we entangled it. So we need to - // entangle it again, just to be sure. - - markRootEntangled(root, newQueueLanes); - } + scheduleUpdateOnFiber(fiber, lane, eventTime); } } @@ -11490,7 +11150,6 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; - var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11620,7 +11279,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11718,7 +11376,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11816,7 +11473,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -11914,7 +11570,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12027,7 +11682,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12140,7 +11794,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - InvalidNestedHooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12174,6034 +11827,5278 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; currentHookNameInDev = "useLayoutEffect"; warnInvalidHookAccess(); updateHookTypesDev(); - return updateLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; -} - -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; - -function getCommitTime() { - return commitTime; -} - -function recordCommitTime() { - commitTime = now$1(); -} - -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); - - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); - } -} - -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} - -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; - - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; - } - - profilerStartTime = -1; - } -} - -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; - - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} - -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 -) { - // 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; - - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } - - 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 (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - try { - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); - } finally { - reenableLogs(); - } - } - - setIsRendering(false); - } - - 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 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; - - { - 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. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - 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", - getComponentName(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 _type = Component.type; - 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", - getComponentName(_type) - ); - } - } - - var currentChild = current.child; // This is always exactly one 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 - - 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, - 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; - - 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 { - 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", - getComponentName(outerMemoType) - ); - } - } - } - } - - if (current !== null) { - var prevProps = current.memoizedProps; - - 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 (!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 accumlated 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; - } - } - } - - return updateFunctionComponent( - 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. - - 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. - // TODO: Figure out what we should do in Blocking mode. - 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. - - { - markSpawnedWork(OffscreenLane); - } - - 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); - 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; - - if (prevState !== null) { - // We're going from hidden -> visible. - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); - - 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; - } - - 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. - -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 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 markRef(current, workInProgress) { - var ref = workInProgress.ref; - - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } -} - -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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } - - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } - - var nextChildren; - prepareToReadContext(workInProgress, renderLanes); - - { - 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 - ); - } finally { - reenableLogs(); - } - } - - setIsRendering(false); - } - - 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 updateClassComponent( - 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 (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(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. - - var hasContext; - - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } - - 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 - - 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 - ); - - { - var inst = workInProgress.stateNode; - - 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.", - getComponentName(workInProgress.type) || "a component" - ); - } - - didWarnAboutReassigningProps = true; - } - } - - 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; - - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } - - 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; - - { - stopProfilerTimerIfRunning(); - } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); - - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - 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 pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; - - 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." - ); - } - - 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); - } + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - 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); - } + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - return workInProgress.child; + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; } -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 (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; - } +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; - markRef(current, workInProgress); - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; +function getCommitTime() { + return commitTime; } -function updateHostText(current, workInProgress) { - // immediately after. - - return null; +function recordCommitTime() { + commitTime = now$1(); } -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 +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); - workInProgress.flags |= Placement; + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); } +} - 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. - - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; - - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } - - child = updateFunctionComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - 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; - } - - case MemoComponent: { - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = Component.propTypes; - - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - resolvedProps, // Resolved for outer only - "prop", - getComponentName(Component) - ); - } - } - } - - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; - } - } +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} - var hint = ""; +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; - { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; } - } // 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 - ); + profilerStartTime = -1; } } -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 +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } +} - 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 ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; - var hasContext; +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); +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 { - hasContext = false; + // 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 + ); } +} - prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( +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, - Component, - true, - hasContext, + null, + nextChildren, renderLanes ); } -function mountIndeterminateComponent( - _current, +function updateForwardRef( + 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; - + // 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.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; + 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 (!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 + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) ); - - didWarnAboutBadClass[componentName] = true; } } + } - if (workInProgress.mode & StrictLegacyMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent - setIsRendering(true); + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); + + { ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, + setIsRendering(true); + nextChildren = renderWithHooks( + current, workInProgress, - Component, - props, - context, + render, + nextProps, + ref, renderLanes ); - setIsRendering(false); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - - { - // 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 = getComponentName(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 - ); - didWarnAboutModulePatternComponent[_componentName] = true; - } - } - } - - 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 = getComponentName(Component) || "Unknown"; + if (workInProgress.mode & StrictMode) { + disableLogs(); - 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 + try { + nextChildren = renderWithHooks( + current, + workInProgress, + render, + nextProps, + ref, + renderLanes ); - - didWarnAboutModulePatternComponent[_componentName2] = true; + } finally { + reenableLogs(); } - } // Proceed under the assumption that this is a class instance + } - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + setIsRendering(false); + } - 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 (current !== null && !didReceiveUpdate) { + bailoutHooks(current, workInProgress, renderLanes); + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } // React DevTools reads this flag. - var hasContext = false; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } +function updateMemoComponent( + current, + workInProgress, + Component, + nextProps, + updateLanes, + renderLanes +) { + if (current === null) { + var type = Component.type; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + if ( + isSimpleFunctionComponent(type) && + Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either. + Component.defaultProps === undefined + ) { + var resolvedType = type; - if (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( + { + 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. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, workInProgress, - Component, - getDerivedStateFromProps, - props + resolvedType, + nextProps, + updateLanes, + renderLanes ); } - adoptClassInstance(workInProgress, value); - mountClassInstance(workInProgress, Component, props, renderLanes); - return finishClassComponent( + { + 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", + getComponentName(type) + ); + } + } + + var child = createFiberFromTypeAndProps( + Component.type, null, + nextProps, workInProgress, - Component, - true, - hasContext, + workInProgress.mode, renderLanes ); - } else { - // Proceed under the assumption that this is a function component - workInProgress.tag = FunctionComponent; + child.ref = workInProgress.ref; + child.return = workInProgress; + workInProgress.child = child; + return child; + } - { - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); + { + var _type = Component.type; + var _innerPropTypes = _type.propTypes; - try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); - } finally { - reenableLogs(); - } - } + 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", + getComponentName(_type) + ); } + } - reconcileChildren(null, workInProgress, value, renderLanes); + var currentChild = current.child; // This is always exactly one child - { - validateFunctionComponentInDev(workInProgress, Component); - } + 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 - return workInProgress.child; - } -} + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; -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 (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } + } // React DevTools reads this flag. - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + workInProgress.flags |= PerformedWork; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; +} - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } +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; - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + 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 (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; + var outerPropTypes = outerMemoType && outerMemoType.propTypes; - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) + ); + } } } + } - if (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; - - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); - - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } + if (current !== null) { + var prevProps = current.memoizedProps; if ( - typeof Component.contextType === "object" && - Component.contextType !== null + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type ) { - var _componentName4 = getComponentName(Component) || "Unknown"; + didReceiveUpdate = false; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 + 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 accumlated 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 ); - - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; + } 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; } } } -} - -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes, - cachePool: getSuspendedCachePool() - }; + return updateFunctionComponent( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); } -function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { - var cachePool = null; - - return { - baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes), - cachePool: cachePool - }; -} // TODO: Probably should inline this back +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; -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; + if ( + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" + ) { + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Figure out what we should do in Blocking mode. + var nextState = { + baseLanes: NoLanes + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + var nextBaseLanes; - 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 (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. - return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); -} + { + markSpawnedWork(OffscreenLane); + } -function getRemainingWorkInPrimaryTree(current, renderLanes) { - // TODO: Should not remove render lanes that were pinged during this render - return removeLanes(current.childLanes, renderLanes); -} + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes + }; + workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. + pushRenderLanes(workInProgress, nextBaseLanes); + return null; + } else { + // Rendering at offscreen, so we can clear the base lanes. + var _nextState2 = { + baseLanes: NoLanes + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. - { - if (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; + var subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); } - } + } else { + var _subtreeRenderLanes; - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + if (prevState !== null) { + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state - 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. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext - ); - } + 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; } - } - 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. + pushRenderLanes(workInProgress, _subtreeRenderLanes); + } - if (current === null) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); + 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. - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; +var updateLegacyHiddenComponent = updateOffscreenComponent; - 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 - ); +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - 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. +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - workInProgress.lanes = SomeRetryLane; +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, - { - markSpawnedWork(SomeRetryLane); - } + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } - 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; + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - if (prevState !== null) { - if (showFallback) { - var _nextFallbackChildren2 = nextProps.fallback; - var _nextPrimaryChildren2 = nextProps.children; +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - var _fallbackChildFragment = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren2, - _nextFallbackChildren2, - renderLanes - ); + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } +} - 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; +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; - var _primaryChildFragment4 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren3, - renderLanes + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) ); - - 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; + } + } - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); + var context; - 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 unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); + } - 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 nextChildren; + prepareToReadContext(workInProgress, renderLanes); - var _primaryChildFragment6 = updateSuspensePrimaryChildren( + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + + if (workInProgress.mode & StrictMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( current, workInProgress, - _nextPrimaryChildren5, + Component, + nextProps, + context, renderLanes ); - - workInProgress.memoizedState = null; - return _primaryChildFragment6; + } finally { + reenableLogs(); } } + + setIsRendering(false); } -} -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; + 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 mountSuspenseFallbackChildren( +function updateClassComponent( + current, workInProgress, - primaryChildren, - fallbackChildren, + Component, + nextProps, renderLanes ) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; - - if ((mode & BlockingMode) === 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.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 (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 (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(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. - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + var hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null + hasContext = false; + } + + 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 + + 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 ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null + } else { + 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 & BlockingMode) === 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.", + getComponentName(workInProgress.type) || "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(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); + } + + var instance = workInProgress.stateNode; // Rerender + + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === 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 + didCaptureError && + typeof Component.getDerivedStateFromError !== "function" ) { - 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. + // 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 & StrictMode) { + 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; - - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; - - 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; - } +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - if (node === workInProgress) { - return; - } + 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." + ); + } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState !== null ? prevState.element : null; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property + // being called "element". - node = node.return; - } + var nextChildren = nextState.element; - node.sibling.return = node.return; - node = node.sibling; + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, 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; + var root = workInProgress.stateNode; - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; + 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; } - - row = row.sibling; + } else { + // Otherwise reset hydration state in case we aborted and resumed another + // root. + reconcileChildren(current, workInProgress, nextChildren, renderLanes); } - return lastContentRow; + return workInProgress.child; } -function validateRevealOrder(revealOrder) { - { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; +function updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); - 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 type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - break; - } + 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; + } - 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() - ); + markRef(current, workInProgress); + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - break; - } +function updateHostText(current, workInProgress) { + // immediately after. - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + return null; +} - break; - } - } else { - error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); - } - } +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 + + workInProgress.flags |= Placement; } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + 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. - 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; + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; - error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + Component ); } - } - } -} - -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; - 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 = updateFunctionComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes ); - - return false; + return child; } - } - return true; -} + case ClassComponent: { + { + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); + } -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - if (!validateSuspenseListNestedChild(children[i], i)) { - return; - } - } - } else { - var iteratorFn = getIteratorFn(children); + child = updateClassComponent( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - if (typeof iteratorFn === "function") { - var childrenIterator = iteratorFn.call(children); + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component + ); + } - if (childrenIterator) { - var step = childrenIterator.next(); - var _i = 0; + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; - _i++; - } + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); } - } 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 - ); } } + + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } + } + + 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 + ); } } -function initSuspenseListRenderState( +function mountIncompleteClassComponent( + _current, workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode + Component, + nextProps, + renderLanes ) { - var renderState = workInProgress.memoizedState; + 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 (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }; + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. + + 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 hasContext; + + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); } 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; + hasContext = false; } -} // 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 + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes ); +} - 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 - ); - } +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 - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + workInProgress.flags |= Placement; } - pushSuspenseContext(workInProgress, suspenseContext); + var props = workInProgress.pendingProps; + var context; - if ((workInProgress.mode & BlockingMode) === 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; + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); + } - 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); + var value; - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; + + 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; + + didWarnAboutBadClass[componentName] = true; } + } - 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; + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + setIsRendering(false); + } // React DevTools reads this flag. - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + workInProgress.flags |= PerformedWork; - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + { + // 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 = getComponentName(Component) || "Unknown"; - initSuspenseListRenderState( - workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode + 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 ); - break; + + didWarnAboutModulePatternComponent[_componentName] = true; } + } + } - case "together": { - initSuspenseListRenderState( - workInProgress, - false, // isBackwards - null, // tail - null, // last - undefined + 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 = getComponentName(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 ); - break; - } - default: { - // The default reveal order is the same as not having - // a boundary. - workInProgress.memoizedState = null; + 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; } - } - return workInProgress.child; -} + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); + } - 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, + adoptClassInstance(workInProgress, value); + mountClassInstance(workInProgress, Component, props, renderLanes); + return finishClassComponent( null, - nextChildren, + workInProgress, + Component, + true, + hasContext, renderLanes ); } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - } + // Proceed under the assumption that this is a function component + workInProgress.tag = FunctionComponent; - return workInProgress.child; -} + { + if (workInProgress.mode & StrictMode) { + disableLogs(); -var hasWarnedAboutUsingNoValuePropOnContextProvider = false; + try { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + } finally { + reenableLogs(); + } + } + } -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; + reconcileChildren(null, workInProgress, value, renderLanes); - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; + { + validateFunctionComponentInDev(workInProgress, Component); + } + + return workInProgress.child; + } +} +function validateFunctionComponentInDev(workInProgress, Component) { + { + if (Component) { + if (Component.childContextTypes) { error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" ); } } - var providerPropTypes = workInProgress.type.propTypes; + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); - } - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - pushProvider(workInProgress, context, newValue); + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - if (changedBits === 0) { - // No change. Bailout early if children are the same. - if (oldProps.children === newProps.children && !hasContextChanged()) { - return bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; + + error( + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info ); } - } else { - // The context value changed. Search for matching consumers and schedule - // them to update. - propagateContextChange(workInProgress, context, changedBits, renderLanes); } - } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; -var hasWarnedAboutUsingContextAsConsumer = false; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { + error( + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 + ); -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. + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } + } - { - 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 ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; - error( - "Rendering directly is not supported and will be removed in " + - "a future major release. Did you mean to render instead?" - ); - } + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { + error( + "%s: Function components do not support contextType.", + _componentName4 + ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; } - } else { - context = context._context; } } +} - var newProps = workInProgress.pendingProps; - var render = newProps.children; +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; + +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes + }; +} - { - 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." - ); - } - } +function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) + }; +} // TODO: Probably should inline this back - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; +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; - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. + 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. - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); } -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); } -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; + } } - markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - 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; + 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 { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; + // 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. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } } -} -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; + 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 (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + 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 + ); - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + 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. - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); + workInProgress.lanes = SomeRetryLane; + + { + markSpawnedWork(SomeRetryLane); } - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + 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; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } - } + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - 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 _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 deletions = returnFiber.deletions; + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes + ); - if (deletions === null) { - returnFiber.deletions = [current]; - returnFiber.flags |= ChildDeletion; + workInProgress.memoizedState = null; + return _primaryChildFragment4; + } } else { - deletions.push(current); - } + // 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 + ); - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. + 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. - return newWorkInProgress; - } -} + workInProgress.memoizedState = SUSPENDED_MARKER; + return _fallbackChildFragment2; + } else { + // Still haven't timed out. Continue rendering the children, like we + // normally do. + var _nextPrimaryChildren5 = nextProps.children; -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; + var _primaryChildFragment6 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren5, + 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 - ) - ); + workInProgress.memoizedState = null; + return _primaryChildFragment6; + } } } +} - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; +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; +} - 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. +function mountSuspenseFallbackChildren( + workInProgress, + primaryChildren, + fallbackChildren, + renderLanes +) { + var mode = workInProgress.mode; + var progressedPrimaryFragment = workInProgress.child; + var primaryChildProps = { + mode: "hidden", + children: primaryChildren + }; + var primaryChildFragment; + var fallbackChildFragment; - switch (workInProgress.tag) { - case HostRoot: - pushHostRootContext(workInProgress); - break; + if ((mode & BlockingMode) === 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; - case HostComponent: - pushHostContext(workInProgress); - break; + 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; + } - case ClassComponent: { - var Component = workInProgress.type; + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } else { + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); + } - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); - } + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - break; - } +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); +} - case HostPortal: - pushHostContainer( - workInProgress, - workInProgress.stateNode.containerInfo - ); - break; +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren + } + ); - case ContextProvider: { - var newValue = workInProgress.memoizedProps.value; - var context = workInProgress.type._context; - pushProvider(workInProgress, context, newValue); - break; - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; + } - case Profiler: - { - // Profiler should only call onRender when one of its descendants actually rendered. - var hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - 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, + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + currentFallbackChildFragment.nextEffect = null; + currentFallbackChildFragment.flags = Deletion; + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; + } - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; - } + workInProgress.child = primaryChildFragment; + return primaryChildFragment; +} - break; +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 SuspenseComponent: { - var state = workInProgress.memoizedState; + if ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === 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 (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) { + // 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 effect during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. So we need to remove it from the list. Deletions are stored + // on the same list as effects. We want to keep the effects from the primary + // tree. So we copy the primary child fragment's effect list, which does not + // include the fallback deletion effect. - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; + var progressedLastEffect = primaryChildFragment.lastEffect; - 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. + if (progressedLastEffect !== null) { + workInProgress.firstEffect = primaryChildFragment.firstEffect; + workInProgress.lastEffect = progressedLastEffect; + progressedLastEffect.nextEffect = null; + } else { + // TODO: Reset this somewhere else? Lol legacy mode is so weird. + workInProgress.firstEffect = workInProgress.lastEffect = null; + } + } else { + primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); + } - var child = bailoutOnAlreadyFinishedWork( - current, - workInProgress, - renderLanes - ); + var fallbackChildFragment; - if (child !== null) { - // The fallback children have pending work. Skip over the - // primary children and work on the fallback. - return child.sibling; - } else { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) - ); - } + 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. - break; - } + fallbackChildFragment.flags |= Placement; + } - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; +} - var _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - 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. + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - 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. + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - var renderState = workInProgress.memoizedState; +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 (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; - } + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + 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; + } - 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 (node === workInProgress) { + return; + } - 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); - } + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - 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; - } + node = node.return; } - } 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; + node.sibling.return = node.return; + node = node.sibling; + } +} - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - 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; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, - workInProgress, - elementType, - updateLanes, - renderLanes - ); - } + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - 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 (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + 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 _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + break; + } - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); - } + 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() + ); - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); + break; + } - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); - case HostText: - return updateHostText(); + break; + } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } +} - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - case HostPortal: - return updatePortalComponent(current, workInProgress, 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; - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); +function validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - return updateForwardRef( - current, - workInProgress, + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; + + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", type, - _resolvedProps2, - renderLanes + index, + type ); - } - - case Fragment: - return updateFragment(current, workInProgress, renderLanes); - case Mode: - return updateMode(current, workInProgress, renderLanes); - - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); + return false; + } + } - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + return true; +} - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; + } + } + } else { + var iteratorFn = getIteratorFn(children); - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. + if (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); + if (childrenIterator) { + var step = childrenIterator.next(); + var _i = 0; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + for (; !step.done; step = childrenIterator.next()) { + if (!validateSuspenseListNestedChild(step.value, _i)) { + return; + } - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); + _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 + ); } } - - _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 - ); - } +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering + }; + } 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; + renderState.lastEffect = lastEffectBeforeRendering; + } +} // 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 _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - return mountIncompleteClassComponent( - current, + 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, - _Component3, - _resolvedProps4, + workInProgress.child, renderLanes ); } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - case ScopeComponent: { - break; - } + pushSuspenseContext(workInProgress, suspenseContext); - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); - } + if ((workInProgress.mode & BlockingMode) === 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; - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); - } - } + 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; + } - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode, + workInProgress.lastEffect + ); + break; + } -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; -} + 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; -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; -} + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. -function hadNoMutationsEffects(current, completedWork) { - var didBailout = current !== null && current.child === completedWork.child; + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - if (didBailout) { - return true; - } + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - 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`. + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect + ); + break; + } - var child = completedWork.child; + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect + ); + break; + } - while (child !== null) { - if ( - (child.flags & MutationMask) !== NoFlags || - (child.subtreeFlags & MutationMask) !== NoFlags - ) { - return false; + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } } - - child = child.sibling; } - return true; + return workInProgress.child; } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; - -{ - // 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; - - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } - - appendInitialChild(parent, instance); - } else if (node.tag === HostText) { - var _instance = node.stateNode; - - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance = cloneHiddenTextInstance(); - } - - appendInitialChild(parent, _instance); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; - - if (newIsHidden) { - var primaryChildParent = node.child; - - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildren( - parent, - primaryChildParent, - true, - newIsHidden - ); - } - - var fallbackChildParent = primaryChildParent.sibling; +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } - } + 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); + } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; - } - } 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. + return workInProgress.child; +} - node = node; +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - if (node === workInProgress) { - return; - } +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 (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; - node = node.return; + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); } - - node.sibling.return = node.return; - node = node.sibling; } - }; // 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; + var providerPropTypes = workInProgress.type.propTypes; - while (node !== null) { - // eslint-disable-next-line no-labels - if (node.tag === HostComponent) { - var instance = node.stateNode; + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); + } + } - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var props = node.memoizedProps; - var type = node.type; - instance = cloneHiddenInstance(instance); - } + pushProvider(workInProgress, newValue); - appendChildToContainerChildSet(containerChildSet, instance); - } else if (node.tag === HostText) { - var _instance2 = node.stateNode; + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - if (needsVisibilityToggle && isHidden) { - // This child is inside a timed out tree. Hide it. - var text = node.memoizedProps; - _instance2 = cloneHiddenTextInstance(); - } + if (changedBits === 0) { + // 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, changedBits, renderLanes); + } + } - appendChildToContainerChildSet(containerChildSet, _instance2); - } else if (node.tag === HostPortal); - else if (node.tag === SuspenseComponent) { - if ((node.flags & Update) !== NoFlags) { - // Need to toggle the visibility of the primary children. - var newIsHidden = node.memoizedState !== null; + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - if (newIsHidden) { - var primaryChildParent = node.child; +var hasWarnedAboutUsingContextAsConsumer = false; - if (primaryChildParent !== null) { - if (primaryChildParent.child !== null) { - primaryChildParent.child.return = primaryChildParent; - appendAllChildrenToContainer( - containerChildSet, - primaryChildParent, - true, - newIsHidden - ); - } +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. - var fallbackChildParent = primaryChildParent.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; - if (fallbackChildParent !== null) { - fallbackChildParent.return = node; - node = fallbackChildParent; - continue; - } - } - } + 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; + } + } - if (node.child !== null) { - // Continue traversing like normal - node.child.return = node; - node = node.child; - continue; - } - } 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 newProps = workInProgress.pendingProps; + var render = newProps.children; - node = node; + { + 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 (node === workInProgress) { - return; - } + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + { + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. - node = node.return; - } + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - node.sibling.return = node.return; - node = node.sibling; - } - }; +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; +} - updateHostContainer = function(current, workInProgress) { - var portalOrRoot = workInProgress.stateNode; - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - 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. + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - appendAllChildrenToContainer(newChildSet, workInProgress, false, false); - portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - markUpdate(workInProgress); - finalizeContainerChildren(container, newChildSet); - } - }; + 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; + } else { + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; + } +} - 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. +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - var childrenUnchanged = hadNoMutationsEffects(current, workInProgress); + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - if (childrenUnchanged && oldProps === newProps) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - var recyclableInstance = workInProgress.stateNode; - var currentHostContext = getHostContext(); - var updatePayload = null; + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - if (oldProps !== newProps) { - updatePayload = prepareUpdate( - recyclableInstance, - type, - oldProps, - newProps - ); - } + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - if (childrenUnchanged && updatePayload === null) { - // No changes, just reuse the existing instance. - // Note that this might release a previous clone. - workInProgress.stateNode = currentInstance; - return; - } + 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."); + } + } - var newInstance = cloneInstance( - currentInstance, - updatePayload, - type, - oldProps, - newProps, - workInProgress, - childrenUnchanged - ); + prevSibling.sibling = newWorkInProgress; + } // Delete the old fiber and place the new one. + // Since the old fiber is disconnected, we have to schedule it manually. - workInProgress.stateNode = newInstance; + var last = returnFiber.lastEffect; - 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); + if (last !== null) { + last.nextEffect = current; + returnFiber.lastEffect = current; } else { - // If children might have changed, we have to add them all to the set. - appendAllChildren(newInstance, workInProgress, false, false); + returnFiber.firstEffect = returnFiber.lastEffect = current; } - }; - 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. + current.nextEffect = null; + current.flags = Deletion; + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - markUpdate(workInProgress); - } else { - workInProgress.stateNode = current.stateNode; - } - }; + return newWorkInProgress; + } } -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 beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; - } + { + 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 + ) + ); + } + } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (current !== null) { + var oldProps = current.memoizedProps; + var newProps = workInProgress.pendingProps; - 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 ( + 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. - break; - } + switch (workInProgress.tag) { + case HostRoot: + pushHostRootContext(workInProgress); + break; - 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; + case HostComponent: + pushHostContext(workInProgress); + break; - while (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + case ClassComponent: { + var Component = workInProgress.type; - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - 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; + break; } - } else { - // Detach the insertion after the last node that was already - // inserted. - _lastTailNode.sibling = null; - } - - break; - } - } -} -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; - - 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; + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; - 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. + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; + 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, - 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. + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } - _child.return = completedWork; - _child = _child.sibling; - } - } + break; - 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; - - 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. - - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; - } - - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; + case SuspenseComponent: { + var state = workInProgress.memoizedState; - 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 (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. - 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. + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - _child3.return = completedWork; - _child3 = _child3.sibling; - } - } + 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. - completedWork.subtreeFlags |= subtreeFlags; - } + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); - completedWork.childLanes = newChildLanes; - return didBailout; -} + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + return null; + } + } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); + } -function completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + break; + } - 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 SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - case ClassComponent: { - var Component = workInProgress.type; + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - if (isContextProvider(Component)) { - popContext(workInProgress); - } + 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. - 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 HostRoot: { - var fiberRoot = workInProgress.stateNode; + var renderState = workInProgress.memoizedState; - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); + 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; + } - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = null; - } + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - 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 (_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 (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; + 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); } } - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); - return null; + 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; + } } + } 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. - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; - - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); - - 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. + workInProgress.lanes = NoLanes; - bubbleProperties(workInProgress); - return null; - } + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - 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. + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - var _wasHydrated = popHydrationState(); + 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 (_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. - } + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - bubbleProperties(workInProgress); - return null; + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); } - case HostText: { - var newText = newProps; + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - 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. + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); - 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. - } + case HostText: + return updateHostText(); - var _rootContainerInstance = getRootHostContainer(); + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - var _currentHostContext = getHostContext(); + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - var _wasHydrated2 = popHydrationState(); + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - bubbleProperties(workInProgress); - return null; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; - - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. + case Mode: + return updateMode(current, workInProgress, renderLanes); - return workInProgress; - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - if (nextDidTimeout && !prevDidTimeout) { - // If this subtree is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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 MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - 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(); - } - } - } + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); { - // TODO: Only schedule updates if not prevDidTimeout. - if (nextDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. - workInProgress.flags |= Update; - } - } - - bubbleProperties(workInProgress); + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - { - 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 doens't support type casting in combiation with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); } } } - return null; + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); - - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } - - bubbleProperties(workInProgress); - return null; - - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } 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 _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - if (isContextProvider(_Component)) { - popContext(workInProgress); - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - bubbleProperties(workInProgress); - return null; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes + ); } case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; - - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; - } - - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; - - 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 (!cannotBeSuspended) { - var row = workInProgress.child; - - while (row !== null) { - var suspended = findFirstSuspended(row); + return updateSuspenseListComponent(current, workInProgress, 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 FundamentalComponent: { + break; + } - var newThennables = suspended.updateQueue; + case ScopeComponent: { + break; + } - 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 OffscreenComponent: { + return updateOffscreenComponent(current, workInProgress, renderLanes); + } - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + case LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } + } - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - return workInProgress.child; - } +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} - row = row.sibling; - } - } +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; +} - 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 appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - workInProgress.lanes = SomeRetryLane; +{ + // 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; - { - markSpawnedWork(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); + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.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 (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var props = node.memoizedProps; + var type = node.type; + instance = cloneHiddenInstance(instance); + } - var _newThennables = _suspended.updateQueue; + appendInitialChild(parent, instance); + } else if (node.tag === HostText) { + var _instance = node.stateNode; - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; - } + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance = cloneHiddenTextInstance(); + } - cutOffTailIfNeeded(renderState, true); // This might have been modified. + appendInitialChild(parent, _instance); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - 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 (newIsHidden) { + var primaryChildParent = node.child; - workInProgress.lanes = SomeRetryLane; + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildren( + parent, + primaryChildParent, + true, + newIsHidden + ); + } - { - markSpawnedWork(SomeRetryLane); + var fallbackChildParent = primaryChildParent.sibling; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } } } } - 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; - - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } - - renderState.last = renderedTail; + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; } - } + } 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 (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. + node = node; - var suspenseContext = suspenseStackCursor.current; + if (node === workInProgress) { + return; + } - if (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. - - return next; + node = node.return; } - bubbleProperties(workInProgress); - return null; + node.sibling.return = node.return; + node = node.sibling; } + }; // An unfortunate fork of appendAllChildren because we have two different parent types. - case ScopeComponent: { - break; - } + 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; - case OffscreenComponent: - case LegacyHiddenComponent: { - popRenderLanes(workInProgress); - var _nextState = workInProgress.memoizedState; - var nextIsHidden = _nextState !== null; + while (node !== null) { + // eslint-disable-next-line no-labels + if (node.tag === HostComponent) { + var instance = node.stateNode; - if (current !== null) { - var _prevState = current.memoizedState; - var prevIsHidden = _prevState !== 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); + } - if ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; + appendChildToContainerChildSet(containerChildSet, instance); + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; + + if (needsVisibilityToggle && isHidden) { + // This child is inside a timed out tree. Hide it. + var text = node.memoizedProps; + _instance3 = cloneHiddenTextInstance(); } - } // Don't bubble properties for hidden children. - if ( - !nextIsHidden || - includesSomeLane(subtreeRenderLanes, OffscreenLane) || - (workInProgress.mode & ConcurrentMode) === NoMode - ) { - bubbleProperties(workInProgress); - } + appendChildToContainerChildSet(containerChildSet, _instance3); + } else if (node.tag === HostPortal); + else if (node.tag === SuspenseComponent) { + if ((node.flags & Update) !== NoFlags) { + // Need to toggle the visibility of the primary children. + var newIsHidden = node.memoizedState !== null; - return null; - } - } + if (newIsHidden) { + var primaryChildParent = node.child; - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + if (primaryChildParent !== null) { + if (primaryChildParent.child !== null) { + primaryChildParent.child.return = primaryChildParent; + appendAllChildrenToContainer( + containerChildSet, + primaryChildParent, + true, + newIsHidden + ); + } -function unwindWork(workInProgress, renderLanes) { - switch (workInProgress.tag) { - case ClassComponent: { - var Component = workInProgress.type; + var fallbackChildParent = primaryChildParent.sibling; + + if (fallbackChildParent !== null) { + fallbackChildParent.return = node; + node = fallbackChildParent; + continue; + } + } + } + } - if (isContextProvider(Component)) { - popContext(workInProgress); - } + if (node.child !== null) { + // Continue traversing like normal + node.child.return = node; + node = node.child; + continue; + } + } 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 flags = workInProgress.flags; + node = node; - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + if (node === workInProgress) { + return; + } - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; } - return workInProgress; + node = node.return; } - return null; + node.sibling.return = node.return; + node = node.sibling; } + }; - case HostRoot: { - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); - var _flags = workInProgress.flags; + updateHostContainer = function(workInProgress) { + var portalOrRoot = workInProgress.stateNode; + var childrenUnchanged = workInProgress.firstEffect === null; - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); - } + 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. - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } + appendAllChildrenToContainer(newChildSet, workInProgress, false, false); + portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container. - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; + markUpdate(workInProgress); + finalizeContainerChildren(container, newChildSet); } + }; - case SuspenseComponent: { - popSuspenseContext(workInProgress); - - var _flags2 = workInProgress.flags; - - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. - - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } + 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 workInProgress; - } + var childrenUnchanged = workInProgress.firstEffect === null; - return null; + if (childrenUnchanged && oldProps === newProps) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. + var recyclableInstance = workInProgress.stateNode; + var currentHostContext = getHostContext(); + var updatePayload = null; - return null; + if (oldProps !== newProps) { + updatePayload = prepareUpdate( + recyclableInstance, + type, + oldProps, + newProps + ); } - case HostPortal: - popHostContainer(workInProgress); - return null; + if (childrenUnchanged && updatePayload === null) { + // No changes, just reuse the existing instance. + // Note that this might release a previous clone. + workInProgress.stateNode = currentInstance; + return; + } - case ContextProvider: - var context = workInProgress.type._context; - popProvider(context, workInProgress); - return null; + var newInstance = cloneInstance( + currentInstance, + updatePayload, + type, + oldProps, + newProps, + workInProgress, + childrenUnchanged + ); - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); + workInProgress.stateNode = newInstance; - return null; + 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); + } + }; - case CacheComponent: - return null; + 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. - default: - return null; - } + markUpdate(workInProgress); + } else { + workInProgress.stateNode = current.stateNode; + } + }; } -function unwindInterruptedWork(interruptedWork, renderLanes) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; +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 (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; + } - break; - } + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + 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; + } - case HostComponent: { - popHostContext(interruptedWork); break; } - case HostPortal: - popHostContainer(interruptedWork); - break; - - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; + 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; - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; + } - case ContextProvider: - var context = interruptedWork.type._context; - popProvider(context, interruptedWork); - break; + _tailNode = _tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); + 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; + } } } -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} - -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} +function completeWork(current, workInProgress, renderLanes) { + var newProps = workInProgress.pendingProps; -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + switch (workInProgress.tag) { + case IndeterminateComponent: + case LazyComponent: + case SimpleMemoComponent: + case FunctionComponent: + case ForwardRef: + case Fragment: + case Mode: + case Profiler: + case ContextConsumer: + case MemoComponent: + return null; -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + case ClassComponent: { + var Component = workInProgress.type; - if (logError === false) { - return; + if (isContextProvider(Component)) { + popContext(workInProgress); + } + + return null; } - var error = errorInfo.value; + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + var fiberRoot = workInProgress.stateNode; - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; + } - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + 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(); - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 + 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; + } } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + updateHostContainer(workInProgress); + return null; + } - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; + + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); + + if (current.ref !== workInProgress.ref) { + markRef$1(workInProgress); + } } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; - } + 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. - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. + return null; + } - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper + 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 _wasHydrated = popHydrationState(); + + 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 (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } + + return null; } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); - } -} -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; + case HostText: { + var newText = newProps; -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. + 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. - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". + 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. + } - update.payload = { - element: null - }; - var error = errorInfo.value; + var _rootContainerInstance = getRootHostContainer(); - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + var _currentHostContext = getHostContext(); - return update; -} + var _wasHydrated2 = popHydrationState(); -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + return null; + } - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; + + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - var inst = fiber.stateNode; + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); + return workInProgress; } - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - logCapturedError(fiber, errorInfo); + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); + } else { + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; } - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + if (nextDidTimeout && !prevDidTimeout) { + // If this subtreee is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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 (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { - error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ); + 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(); } } } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - - return update; -} - -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; - if (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); + { + // TODO: Only schedule updates if not prevDidTimeout. + if (nextDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. + workInProgress.flags |= Update; + } + } - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); + return null; } - } - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); - } -} + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(workInProgress); -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes -) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; - // A legacy mode Suspense quirk, only relevant to hook components. + return null; - var tag = sourceFiber.tag; + case ContextProvider: + // Pop provider fiber + popProvider(workInProgress); + return null; - if ( - (sourceFiber.mode & BlockingMode) === NoMode && - (tag === FunctionComponent || - tag === ForwardRef || - tag === SimpleMemoComponent) - ) { - var currentSource = sourceFiber.alternate; + 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 (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; + if (isContextProvider(_Component)) { + popContext(workInProgress); } + + return null; } - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; - var _workInProgress = returnFiber; + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; + } - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. - // - // If the suspense boundary suspended itself suspended, we don't have to - // do this trick because nothing was partially started. We can just - // directly do a second pass over the fallback in this render and - // pretend we meant to render that directly. + 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 (!cannotBeSuspended) { + var row = workInProgress.child; + + while (row !== null) { + var suspended = findFirstSuspended(row); + + 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. + + var newThennables = suspended.updateQueue; + + 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 list before doing the second pass since that's now invalid. + + if (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } + + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. + + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. + + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } - if ( - (_workInProgress.mode & BlockingMode) === NoMode && - _workInProgress !== returnFiber - ) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + row = row.sibling; + } + } - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + 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. - if (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + workInProgress.lanes = SomeRetryLane; - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); + { + markSpawnedWork(SomeRetryLane); } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. + } + } 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); - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + 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; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. + var _newThennables = _suspended.updateQueue; - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; + } - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + cutOffTailIfNeeded(renderState, true); // This might have been modified. - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We need to delete the row we just rendered. + // Reset the effect list to what it was before we rendered this + // child. The nested children have already appended themselves. + var lastEffect = (workInProgress.lastEffect = + renderState.lastEffect); // Remove any effects that were appended after this point. - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + 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. - var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + workInProgress.lanes = SomeRetryLane; - enqueueCapturedUpdate(workInProgress, _update); - return; - } + { + markSpawnedWork(SomeRetryLane); + } + } + } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; + 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; - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - var _lane = pickArbitraryLane(rootRenderLanes); + renderState.last = renderedTail; + } + } - workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + 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.lastEffect = workInProgress.lastEffect; + 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. - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane - ); + var suspenseContext = suspenseStackCursor.current; - enqueueCapturedUpdate(workInProgress, _update2); - return; + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - break; - } + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - workInProgress = workInProgress.return; - } while (workInProgress !== null); -} + return next; + } -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + return null; + } -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + case FundamentalComponent: { + break; + } -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -var nextEffect = null; + case ScopeComponent: { + break; + } + + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + if (current !== null) { + var _nextState = workInProgress.memoizedState; + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + var nextIsHidden = _nextState !== null; - { - instance.componentWillUnmount(); + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; + } + } + + return null; + } } -}; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance -) { { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." ); - - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, unmountError); - } } } -function safelyDetachRef(current, nearestMountedAncestor) { - var ref = current.ref; +function unwindWork(workInProgress, renderLanes) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; - if (ref !== null) { - if (typeof ref === "function") { - { - { - invokeGuardedCallback(null, ref, null, null); - } + if (isContextProvider(Component)) { + popContext(workInProgress); + } - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, refError); + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - } else { - ref.current = null; + + return null; } - } -} -function safelyCallDestroy(current, nearestMountedAncestor, destroy) { - { - invokeGuardedCallback(null, destroy, null); + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + var _flags = workInProgress.flags; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, error); + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + } + + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; } - } -} -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = prepareForCommit(root.containerInfo); - nextEffect = firstChild; - commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - var shouldFire = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = false; - focusedInstanceHandle = null; - return shouldFire; -} + case SuspenseComponent: { + popSuspenseContext(workInProgress); -function commitBeforeMutationEffects_begin() { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization + var _flags2 = workInProgress.flags; + + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. - var deletions = fiber.deletions; + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var deletion = deletions[i]; - commitBeforeMutationEffectsDeletion(deletion); + return workInProgress; } + + return null; } - var child = fiber.child; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if ( - (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && - child !== null - ) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitBeforeMutationEffects_complete(); + return null; } + + case HostPortal: + popHostContainer(workInProgress); + return null; + + case ContextProvider: + popProvider(workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + return null; + + default: + return null; } } -function commitBeforeMutationEffects_complete() { - while (nextEffect !== null) { - var fiber = nextEffect; - - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitBeforeMutationEffectsOnFiber, - null, - fiber - ); +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - resetCurrentFiber(); + break; } - var sibling = fiber.sibling; + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; + case HostComponent: { + popHostContext(interruptedWork); + break; } - nextEffect = fiber.return; - } -} + case HostPortal: + popHostContainer(interruptedWork); + break; -function commitBeforeMutationEffectsOnFiber(finishedWork) { - var current = finishedWork.alternate; - var flags = finishedWork.flags; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - // Check to see if the focused element was inside of a hidden (Suspense) subtree. - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - finishedWork.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, finishedWork) && - doesFiberContain(finishedWork, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(finishedWork); + case ContextProvider: + popProvider(interruptedWork); + break; - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - break; - } + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); + break; + } +} - case ClassComponent: { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if (logError === false) { + return; + } - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + var error = errorInfo.value; - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - break; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - case HostRoot: { - break; + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); + + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); + } else { + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - break; + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper } - - resetCurrentFiber(); + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); } } -function commitBeforeMutationEffectsDeletion(deletion) { - // TODO (effects) It would be nice to avoid calling doesFiberContain() - // Maybe we can repurpose one of the subtreeFlags positions for this instead? - // Use it to store which part of the tree the focused instance is in? - // This assumes we can safely determine that instance during the "render" phase. - if (doesFiberContain(deletion, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } -} +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor -) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". - do { - if ((effect.tag & flags) === flags) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + update.payload = { + element: null + }; + var error = errorInfo.value; - if (destroy !== undefined) { - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); - } - } + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - effect = effect.next; - } while (effect !== firstEffect); - } + return update; } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - { - var destroy = effect.destroy; + var inst = fiber.stateNode; - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); + } - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + + logCapturedError(fiber, errorInfo); + } + + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); + { + if (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" ); } } } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - effect = effect.next; - } while (effect !== firstEffect); + return update; +} + +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; + + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); + + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } + + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); } } -function commitLayoutEffectOnFiber( - finishedRoot, - current, - finishedWork, - committedLanes -) { - if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes +) { + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. + + sourceFiber.firstEffect = sourceFiber.lastEffect = null; + + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; - break; + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; } + } - case ClassComponent: { - var instance = finishedWork.stateNode; + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + var _workInProgress = returnFiber; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; + } else { + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if ((_workInProgress.mode & BlockingMode) === NoMode) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; + + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - var updateQueue = finishedWork.updateQueue; + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - commitUpdateQueue(finishedWork, updateQueue, instance); - } + _workInProgress = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - break; - } + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. + + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; + do { + switch (workInProgress.tag) { case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; - - if (_updateQueue !== null) { - var _instance = null; - - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; - - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - break; + enqueueCapturedUpdate(workInProgress, _update); + return; } - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - commitMount(); - } + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - break; - } + var _lane = pickArbitraryLane(rootRenderLanes); - case HostText: { - // We have no life-cycles associated with text. - break; - } + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - case HostPortal: { - // We have no life-cycles associated with portals. - break; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); - var phase = current === null ? "mount" : "update"; - - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - phase, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } + enqueueCapturedUpdate(workInProgress, _update2); + return; } break; - } + } - case SuspenseComponent: { - break; - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); +} - case SuspenseListComponent: - case IncompleteClassComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - break; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - default: { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} + +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; + +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; + + { + instance.componentWillUnmount(); } +}; // Capture errors so they don't interrupt unmounting. +function safelyCallComponentWillUnmount(current, instance) { { - if (finishedWork.flags & Ref) { - commitAttachRef(finishedWork); + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, unmountError); } } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; - - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag - if (typeof ref === "function") { { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); + { + invokeGuardedCallback(null, ref, null, null); } - } - ref.current = instanceToUse; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, refError); + } + } + } else { + ref.current = null; } } } -function commitDetachRef(current) { - var currentRef = current.ref; +function safelyCallDestroy(current, destroy) { + { + invokeGuardedCallback(null, destroy, null); - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, error); } } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel -) { - onCommitUnmount(current); +} - switch (current.tag) { +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case MemoComponent: case SimpleMemoComponent: { - var updateQueue = current.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case ClassComponent: { + if (finishedWork.flags & Snapshot) { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (destroy !== undefined) { - if ((tag & Layout) !== NoFlags$1) { - { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); } } + } - effect = effect.next; - } while (effect !== firstEffect); - } - } - - return; - } - - case ClassComponent: { - safelyDetachRef(current, nearestMountedAncestor); - var instance = current.stateNode; + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance - ); - } + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - return; - } + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - case HostComponent: { - safelyDetachRef(current, nearestMountedAncestor); - return; - } + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. - { - emptyPortalContainer(current); + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } } return; } - case DehydratedFragment: { - return; - } - - case ScopeComponent: { + case HostRoot: { return; } - } -} - -function commitNestedUnmounts( - finishedRoot, - root, - nearestMountedAncestor, - renderPriorityLevel -) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. - - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - !supportsMutation - ) { - node.child.return = node; - node = node.child; - continue; - } - if (node === root) { + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; } -} - -function detachFiberMutation(fiber) { - // Cut off the return pointer to disconnect it from the tree. - // This enables us to detect and warn against state updates on an unmounted component. - // It also prevents events from bubbling from within disconnected components. - // - // Ideally, we should also clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. - // This child itself will be GC:ed when the parent updates the next time. - // - // Note that we can't clear child or sibling pointers yet. - // They're needed for passive effects and for findDOMNode. - // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). - // - // Don't reset the alternate yet, either. We need that so we can detach the - // alternate's fields in the passive phase. Clearing the return pointer is - // sufficient for findDOMNode semantics. - fiber.return = null; -} - -function detachFiberAfterEffects(fiber) { - // Null out fields to improve GC for references that may be lingering (e.g. DevTools). - // Note that we already cleared the return pointer in detachFiberMutation(). - fiber.alternate = null; - fiber.child = null; - fiber.deletions = null; - fiber.dependencies = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; - fiber.updateQueue = null; { - fiber._debugOwner = null; + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function emptyPortalContainer(current) { - var portal = current.stateNode; - var containerInfo = portal.containerInfo; - var emptyChildSet = createContainerChildSet(containerInfo); -} +function commitHookEffectListUnmount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; -function commitContainer(finishedWork) { - switch (finishedWork.tag) { - case ClassComponent: - case HostComponent: - case HostText: { - return; - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + if ((effect.tag & tag) === tag) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; - case HostRoot: - case HostPortal: { - var portalOrRoot = finishedWork.stateNode; - var containerInfo = portalOrRoot.containerInfo, - pendingChildren = portalOrRoot.pendingChildren; - return; - } - } + if (destroy !== undefined) { + destroy(); + } + } - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); + effect = effect.next; + } while (effect !== firstEffect); } } -function commitDeletion( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel -) { - { - // Detach refs and call componentWillUnmount() on the whole subtree. - commitNestedUnmounts(finishedRoot, current, nearestMountedAncestor); - } +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var alternate = current.alternate; - detachFiberMutation(current); + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (alternate !== null) { - detachFiberMutation(alternate); - } -} + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); -function commitWork(current, finishedWork) { - { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); - } + var destroy = effect.destroy; - return; - } + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; - case Profiler: { - return; - } + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); - return; + error( + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum + ); + } + } } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); - return; - } + effect = effect.next; + } while (effect !== firstEffect); + } +} - case HostRoot: { - break; - } +function schedulePassiveEffects(finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - case OffscreenComponent: - case LegacyHiddenComponent: { - return; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; + + do { + var _effect = effect, + next = _effect.next, + tag = _effect.tag; + + if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { + enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); + enqueuePendingPassiveHookEffectMount(finishedWork, effect); } - } - commitContainer(finishedWork); - return; + effect = next; + } while (effect !== firstEffect); } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } - if (newState !== null) { - markCommitTimeOfFallback(); - } -} + schedulePassiveEffects(finishedWork); + return; + } -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; + case ClassComponent: { + var instance = finishedWork.stateNode; - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } } - } - retryCache.add(wakeable); - wakeable.then(retry, retry); - } - }); - } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; + var updateQueue = finishedWork.updateQueue; - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; - } - } + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - return false; -} + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - nextEffect = firstChild; - commitMutationEffects_begin(root, renderPriorityLevel); -} + commitUpdateQueue(finishedWork, updateQueue, instance); + } -function commitMutationEffects_begin(root, renderPriorityLevel) { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization + return; + } - var deletions = fiber.deletions; + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; + if (_updateQueue !== null) { + var _instance = null; - { - invokeGuardedCallback( - null, - commitDeletion, - null, - root, - childToDelete, - fiber, - renderPriorityLevel - ); + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(childToDelete, fiber, error); + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; } } - } - } - var child = fiber.child; + commitUpdateQueue(finishedWork, _updateQueue, _instance); + } - if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitMutationEffects_complete(root, renderPriorityLevel); + return; } - } -} -function commitMutationEffects_complete(root, renderPriorityLevel) { - while (nextEffect !== null) { - var fiber = nextEffect; - - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitMutationEffectsOnFiber, - null, - fiber, - root, - renderPriorityLevel - ); + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + commitMount(); } - resetCurrentFiber(); + return; } - var sibling = fiber.sibling; - - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; + case HostText: { + // We have no life-cycles associated with text. return; } - nextEffect = fiber.return; - } -} + case HostPortal: { + // We have no life-cycles associated with portals. + return; + } -function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { - var flags = finishedWork.flags; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); - if (flags & Ref) { - var current = finishedWork.alternate; + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + current === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } + } + } - if (current !== null) { - commitDetachRef(current); + return; } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. - var primaryFlags = flags & (Placement | Update | Hydrating); - - switch (primaryFlags) { - case Placement: { - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. - - finishedWork.flags &= ~Placement; - break; + case SuspenseComponent: { + return; } - case PlacementAndUpdate: { - // inserted, before any life-cycles like componentDidMount gets called. + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + return; + } + + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } +} - finishedWork.flags &= ~Placement; // Update +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - var _current = finishedWork.alternate; - commitWork(_current, finishedWork); - break; - } + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; - case Hydrating: { - finishedWork.flags &= ~Hydrating; - break; - } + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; - case HydratingAndUpdate: { - finishedWork.flags &= ~Hydrating; // Update + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag - var _current2 = finishedWork.alternate; - commitWork(_current2, finishedWork); - break; - } + if (typeof ref === "function") { + { + ref(instanceToUse); + } + } else { + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } + } - case Update: { - var _current3 = finishedWork.alternate; - commitWork(_current3, finishedWork); - break; + ref.current = instanceToUse; } } } -function commitLayoutEffects(finishedWork, root, committedLanes) { - nextEffect = finishedWork; - commitLayoutEffects_begin(finishedWork, root, committedLanes); -} - -function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { - while (nextEffect !== null) { - var fiber = nextEffect; - var firstChild = fiber.child; +function commitDetachRef(current) { + var currentRef = current.ref; - if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); - nextEffect = firstChild; + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); + } } else { - commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + currentRef.current = null; } } -} +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay -function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { - while (nextEffect !== null) { - var fiber = nextEffect; +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); - if ((fiber.flags & LayoutMask) !== NoFlags) { - var current = fiber.alternate; + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current.updateQueue; - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitLayoutEffectOnFiber, - null, - root, - current, - fiber, - committedLanes - ); + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); - } + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - resetCurrentFiber(); - } - } + do { + var _effect2 = effect, + destroy = _effect2.destroy, + tag = _effect2.tag; - if (fiber === subtreeRoot) { - nextEffect = null; - return; - } + if (destroy !== undefined) { + if ((tag & Passive$1) !== NoFlags$1) { + enqueuePendingPassiveHookEffectUnmount(current, effect); + } else { + { + safelyCallDestroy(current, destroy); + } + } + } - var sibling = fiber.sibling; + effect = effect.next; + } while (effect !== firstEffect); + } + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; return; } - nextEffect = fiber.return; - } -} - -function commitPassiveMountEffects(root, finishedWork) { - nextEffect = finishedWork; - commitPassiveMountEffects_begin(finishedWork, root); -} + case ClassComponent: { + safelyDetachRef(current); + var instance = current.stateNode; -function commitPassiveMountEffects_begin(subtreeRoot, root) { - while (nextEffect !== null) { - var fiber = nextEffect; - var firstChild = fiber.child; + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, instance); + } - if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); - nextEffect = firstChild; - } else { - commitPassiveMountEffects_complete(subtreeRoot, root); + return; } - } -} -function commitPassiveMountEffects_complete(subtreeRoot, root) { - while (nextEffect !== null) { - var fiber = nextEffect; + case HostComponent: { + safelyDetachRef(current); + return; + } - if ((fiber.flags & Passive) !== NoFlags) { + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitPassiveMountOnFiber, - null, - root, - fiber - ); - - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); - } - - resetCurrentFiber(); + emptyPortalContainer(current); } - } - if (fiber === subtreeRoot) { - nextEffect = null; return; } - var sibling = fiber.sibling; - - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; + case FundamentalComponent: { return; } - nextEffect = fiber.return; - } -} - -function commitPassiveMountOnFiber(finishedRoot, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - { - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); - } + case DehydratedFragment: { + return; + } - break; + case ScopeComponent: { + return; } } } -function commitPassiveUnmountEffects(firstChild) { - nextEffect = firstChild; - commitPassiveUnmountEffects_begin(); -} - -function commitPassiveUnmountEffects_begin() { - while (nextEffect !== null) { - var fiber = nextEffect; - var child = fiber.child; - - if ((nextEffect.flags & ChildDeletion) !== NoFlags) { - var deletions = fiber.deletions; +function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - nextEffect = fiberToDelete; - commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - fiberToDelete, - fiber - ); // Now that passive effects have been processed, it's safe to detach lingering pointers. + while (true) { + commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. - var alternate = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + !supportsMutation + ) { + node.child.return = node; + node = node.child; + continue; + } - if (alternate !== null) { - detachFiberAfterEffects(alternate); - } - } + if (node === root) { + return; + } - nextEffect = fiber; + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - } - if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitPassiveUnmountEffects_complete(); + node = node.return; } + + node.sibling.return = node.return; + node = node.sibling; } } -function commitPassiveUnmountEffects_complete() { - while (nextEffect !== null) { - var fiber = nextEffect; +function detachFiberMutation(fiber) { + // Cut off the return pointers to disconnect it from the tree. Ideally, we + // should clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. This child + // itself will be GC:ed when the parent updates the next time. + // Note: we cannot null out sibling here, otherwise it can cause issues + // with findDOMNode and how it requires the sibling field to carry out + // traversal in a later effect. See PR #16820. We now clear the sibling + // field after effects, see: detachFiberAfterEffects. + // + // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. + // It may be required if the current component is an error boundary, + // and one of its descendants throws while unmounting a passive effect. + fiber.alternate = null; + fiber.child = null; + fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.return = null; + fiber.updateQueue = null; - if ((fiber.flags & Passive) !== NoFlags) { - setCurrentFiber(fiber); - commitPassiveUnmountOnFiber(fiber); - resetCurrentFiber(); - } + { + fiber._debugOwner = null; + } +} + +function emptyPortalContainer(current) { + var portal = current.stateNode; + var containerInfo = portal.containerInfo; + var emptyChildSet = createContainerChildSet(containerInfo); +} - var sibling = fiber.sibling; +function commitContainer(finishedWork) { + switch (finishedWork.tag) { + case ClassComponent: + case HostComponent: + case HostText: + case FundamentalComponent: { + return; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; + case HostRoot: + case HostPortal: { + var portalOrRoot = finishedWork.stateNode; + var containerInfo = portalOrRoot.containerInfo, + pendingChildren = portalOrRoot.pendingChildren; return; } + } - nextEffect = fiber.return; + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitPassiveUnmountOnFiber(finishedWork) { +function commitDeletion(finishedRoot, current, renderPriorityLevel) { { - finishedWork.flags &= ~PassiveUnmountPendingDev; - var alternate = finishedWork.alternate; - - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; - } + // Detach refs and call componentWillUnmount() on the whole subtree. + commitNestedUnmounts(finishedRoot, current); } - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - { - commitHookEffectListUnmount( - Passive$1 | HasEffect, - finishedWork, - finishedWork.return - ); - } + var alternate = current.alternate; + detachFiberMutation(current); - break; - } + if (alternate !== null) { + detachFiberMutation(alternate); } } -function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - deletedSubtreeRoot, - nearestMountedAncestor -) { - while (nextEffect !== null) { - var fiber = nextEffect; // Deletion effects fire in parent -> child order - // TODO: Check if fiber has a PassiveStatic flag +function commitWork(current, finishedWork) { + { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListUnmount(Layout | HasEffect, finishedWork); + } - setCurrentFiber(fiber); - commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); - resetCurrentFiber(); - var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag + return; + } - if (child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitPassiveUnmountEffectsInsideOfDeletedTree_complete( - deletedSubtreeRoot - ); - } - } -} + case Profiler: { + return; + } -function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( - deletedSubtreeRoot -) { - while (nextEffect !== null) { - var fiber = nextEffect; + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; + } - if (fiber === deletedSubtreeRoot) { - nextEffect = null; - return; - } + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } - var sibling = fiber.sibling; + case HostRoot: { + break; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; + case OffscreenComponent: + case LegacyHiddenComponent: { + return; + } } - nextEffect = fiber.return; + commitContainer(finishedWork); + return; } } -function commitPassiveUnmountInsideDeletedTreeOnFiber( - current, - nearestMountedAncestor -) { - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - { - commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); - } +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - break; - } + if (newState !== null) { + markCommitTimeOfFallback(); } } -var didWarnWrongReturnPointer = false; +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; -function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { - { - if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { - didWarnWrongReturnPointer = true; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; - error( - "Internal React error: Return pointer is inconsistent " + "with parent." - ); + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + } + + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); + } + } + + retryCache.add(wakeable); + wakeable.then(retry, retry); + } + }); + } +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. + +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; + + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } - } // TODO: Remove this assignment once we're confident that it won't break - // anything, by checking the warning logs for the above invariant + } - fiber.return = expectedReturnFiber; + return false; } var COMPONENT_TYPE = 0; @@ -18283,7 +17180,8 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; +var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -18302,13 +17200,16 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } +var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; +var legacyErrorBoundariesThatAlreadyFailed = null; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority; +var pendingPassiveEffectsRenderPriority = NoPriority$1; var pendingPassiveEffectsLanes = NoLanes; +var pendingPassiveHookEffectsMount = []; +var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -18326,10 +17227,13 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventWipLanes = NoLanes; +var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -18354,41 +17258,63 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority + return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all + // updates at the same priority within the same event. To do this, the inputs + // to the algorithm must be the same. For example, we use the `renderLanes` + // to avoid choosing a lane that is already in the middle of rendering. + // + // However, the "included" lanes could be mutated in between updates in the + // same event, like if you perform an update inside `flushSync`. Or any other + // code path that might call `prepareFreshStack`. + // + // The trick we use is to cache the first of each of these inputs within an + // event. Then reset the cached values once we can be sure the event is over. + // Our heuristic for that is whenever we enter a concurrent work loop. + // + // We'll do the same for `currentEventPendingLanes` below. + + if (currentEventWipLanes === NoLanes) { + currentEventWipLanes = workInProgressRootIncludedLanes; + } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventTransitionLane === NoLane) { - currentEventTransitionLane = claimNextTransitionLane(); + if (currentEventPendingLanes !== NoLanes) { + currentEventPendingLanes = + mostRecentlyUpdatedRoot !== null + ? mostRecentlyUpdatedRoot.pendingLanes + : NoLanes; } - return currentEventTransitionLane; + return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be - // the update lane priority, but for now we're also checking for discrete - // updates and falling back to the scheduler priority. + var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. + // This couples React to the Scheduler internals, so we're replacing it + // with the currentUpdateLanePriority above. As an example of how this + // could be problematic, if we're not inside `Scheduler.runWithPriority`, + // then we'll get the priority of the current running Scheduler task, + // which is probably not what we want. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority + schedulerPriority === UserBlockingPriority$1 ) { - lane = findUpdateLane(InputDiscreteLanePriority); + lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); } else { - { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - lane = findUpdateLane(schedulerLanePriority); - } + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + + lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); } return lane; @@ -18404,12 +17330,16 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority + return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - return claimNextRetryLane(); + if (currentEventWipLanes === NoLanes) { + currentEventWipLanes = workInProgressRootIncludedLanes; + } + + return findRetryLane(currentEventWipLanes); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -18482,8 +17412,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority || - priorityLevel === ImmediatePriority) + (priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority$1) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -18496,9 +17426,13 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } + } // We use this when assigning a lane for a transition inside + // `requestUpdateLane`. We assume it's the same as the root being updated, + // since in the common case of a single root app it probably is. If it's not + // the same root, then it's not a huge deal, we just might batch more stuff + // together more than necessary. - return root; + mostRecentlyUpdatedRoot = root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -18520,7 +17454,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child lanes. + } // Walk the parent path to the root and update the child expiration time. var node = sourceFiber; var parent = sourceFiber.return; @@ -18549,20 +17483,6 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } -} - -function isInterleavedUpdate(fiber, lane) { - return ( - // TODO: Optimize slightly by comparing to root that fiber belongs to. - // Requires some refactoring. Not a big deal though since it's rare for - // concurrent apps to have more than a single root. - workInProgressRoot !== null && - (fiber.mode & BlockingMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), - // then don't treat this as an interleaved update. This pattern is - // accompanied by a warning but we haven't fully deprecated it yet. We can - // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. - deferRenderPhaseUpdateToNextBatch - ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -18586,36 +17506,22 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); + root.callbackNode = null; + root.callbackPriority = NoLanePriority; } - root.callbackNode = null; - root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - var existingCallbackPriority = root.callbackPriority; - - if (existingCallbackPriority === newCallbackPriority) { - { - // If we're going to re-use an existing task, it needs to exist. - // Assume that discrete update microtasks are non-cancellable and null. - // TODO: Temporary until we confirm this warning is not fired. - if ( - existingCallbackNode == null && - existingCallbackPriority !== InputDiscreteLanePriority && - existingCallbackPriority !== SyncLanePriority - ) { - error( - "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." - ); - } - } // The priority hasn't changed. We can reuse the existing task. Exit. + if (existingCallbackNode !== null) { + var existingCallbackPriority = root.callbackPriority; - return; - } + if (existingCallbackPriority === newCallbackPriority) { + // The priority hasn't changed. We can reuse the existing task. Exit. + return; + } // The priority changed. Cancel the existing callback. We'll schedule a new + // one below. - if (existingCallbackNode != null) { - // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -18624,11 +17530,12 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); - newCallbackNode = null; + newCallbackNode = scheduleSyncCallback( + performSyncWorkOnRoot.bind(null, root) + ); } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority, + ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -18646,11 +17553,12 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root, didTimeout) { +function performConcurrentWorkOnRoot(root) { + // Since we know we're in a React event, we can clear the current // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventTransitionLane = NoLanes; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -18680,22 +17588,24 @@ function performConcurrentWorkOnRoot(root, didTimeout) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } // TODO: We only check `didTimeout` defensively, to account for a Scheduler - // bug we're still investigating. Once the bug in Scheduler is fixed, - // we can remove this, since we track expiration ourselves. - - if (didTimeout) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired(root, lanes); // This will schedule a synchronous callback. - - ensureRootIsScheduled(root, now()); - return null; } var exitStatus = renderRootConcurrent(root, lanes); - if (exitStatus !== RootIncomplete) { + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack(root, NoLanes); + } else if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -18887,9 +17797,26 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - } else { - lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // Note that this only happens when part of the tree is rendered + // concurrently. If the whole tree is rendered synchronously, then there + // are no interleaved events. + lanes = getNextLanes(root, lanes); + exitStatus = renderRootSync(root, lanes); + } + } else { + lanes = getNextLanes(root, NoLanes); exitStatus = renderRootSync(root, lanes); } @@ -18967,7 +17894,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); } else { return undefined; } @@ -19023,7 +17950,6 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; - enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -19347,6 +18273,47 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } + + resetChildLanes(completedWork); + + if ( + returnFiber !== null && // Do not append effects to parents if a sibling failed to complete + (returnFiber.flags & Incomplete) === NoFlags + ) { + // Append all the effects of the subtree and this fiber onto the effect + // list of the parent. The completion order of the children affects the + // side-effect order. + if (returnFiber.firstEffect === null) { + returnFiber.firstEffect = completedWork.firstEffect; + } + + if (completedWork.lastEffect !== null) { + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = completedWork.firstEffect; + } + + returnFiber.lastEffect = completedWork.lastEffect; + } // If this fiber had side-effects, we append it AFTER the children's + // side-effects. We can perform certain side-effects earlier if needed, + // by doing multiple passes over the effect list. We don't want to + // schedule our own side-effect on our own list because if end up + // reusing children we'll schedule this effect onto itself since we're + // at the end. + + var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect + // list. PerformedWork effect is read by React DevTools but shouldn't be + // committed. + + if (flags > PerformedWork) { + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = completedWork; + } else { + returnFiber.firstEffect = completedWork; + } + + returnFiber.lastEffect = completedWork; + } + } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -19379,10 +18346,9 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its subtree flags. + // Mark the parent fiber as incomplete and clear its effect list. + returnFiber.firstEffect = returnFiber.lastEffect = null; returnFiber.flags |= Incomplete; - returnFiber.subtreeFlags = NoFlags; - returnFiber.deletions = null; } } @@ -19404,10 +18370,88 @@ function completeUnitOfWork(unitOfWork) { } } +function resetChildLanes(completedWork) { + if ( + // TODO: Move this check out of the hot path by moving `resetChildLanes` + // to switch statement in `completeWork`. + (completedWork.tag === LegacyHiddenComponent || + completedWork.tag === OffscreenComponent) && + completedWork.memoizedState !== null && + !includesSomeLane(subtreeRenderLanes, OffscreenLane) && + (completedWork.mode & ConcurrentMode) !== NoLanes + ) { + // The children of this component are hidden. Don't bubble their + // expiration times. + return; + } + + var newChildLanes = NoLanes; // 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; // 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. + + var shouldBubbleActualDurations = + completedWork.alternate === null || + completedWork.child !== completedWork.alternate.child; + var child = completedWork.child; + + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + + if (shouldBubbleActualDurations) { + actualDuration += child.actualDuration; + } + + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + var isTimedOutSuspense = + completedWork.tag === SuspenseComponent && + completedWork.memoizedState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = completedWork.child; + + if (primaryChildFragment !== null) { + treeBaseDuration -= primaryChildFragment.treeBaseDuration; + } + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + _child = _child.sibling; + } + } + + completedWork.childLanes = newChildLanes; +} + function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority, + ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -19447,8 +18491,7 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; - root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first + root.callbackNode = null; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -19470,39 +18513,27 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // If there are pending passive effects, schedule a callback to process them. - // Do this as early as possible, so it is queued before anything else that - // might get scheduled in the commit phase. (See #16714.) - // TODO: Delete all other places that schedule the passive effect callback - // They're redundant. - - if ( - (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || - (finishedWork.flags & PassiveMask) !== NoFlags - ) { - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority, function() { - flushPassiveEffects(); - return null; - }); + } // Get the list of effects. + + var firstEffect; + + if (finishedWork.flags > PerformedWork) { + // A fiber's effect list consists only of its children, not itself. So if + // the root has an effect, we need to add it to the end of the list. The + // resulting list is the set that would belong to the root's parent, if it + // had one; that is, all the effects in the tree including the root. + if (finishedWork.lastEffect !== null) { + finishedWork.lastEffect.nextEffect = finishedWork; + firstEffect = finishedWork.firstEffect; + } else { + firstEffect = finishedWork; } - } // Check if there are any effects in the whole tree. - // TODO: This is left over from the effect list implementation, where we had - // to check for the existence of `firstEffect` to satsify Flow. I think the - // only other reason this optimization exists is because it affects profiling. - // Reconsider whether this is necessary. - - var subtreeHasEffects = - (finishedWork.subtreeFlags & - (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== - NoFlags; - var rootHasEffect = - (finishedWork.flags & - (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== - NoFlags; - - if (subtreeHasEffects || rootHasEffect) { + } else { + // There is no effect on the root. + firstEffect = finishedWork.firstEffect; + } + + if (firstEffect !== null) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles @@ -19514,18 +18545,58 @@ function commitRootImpl(root, renderPriorityLevel) { // state of the host tree right before we mutate it. This is where // getSnapshotBeforeUpdate is called. - var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( - root, - finishedWork - ); + focusedInstanceHandle = prepareForCommit(root.containerInfo); + shouldFireAfterActiveInstanceBlur = false; + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback(null, commitBeforeMutationEffects, null); + + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var error = clearCaughtError(); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); // We no longer need to track the active instance fiber + + focusedInstanceHandle = null; { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } + } // The next phase is the mutation phase, where we mutate the host tree. + + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback( + null, + commitMutationEffects, + null, + root, + renderPriorityLevel + ); + + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var _error = clearCaughtError(); - commitMutationEffects(root, renderPriorityLevel, finishedWork); + captureCommitPhaseError(nextEffect, _error); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -19533,8 +18604,29 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read + // the host tree after it's been mutated. The idiomatic use case for this is + // layout, but class component lifecycles also fire here for legacy reasons. + + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); - commitLayoutEffects(finishedWork, root, lanes); + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var _error2 = clearCaughtError(); + + captureCommitPhaseError(nextEffect, _error2); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); + + nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an // opportunity to paint. requestPaint(); @@ -19564,6 +18656,22 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; + } else { + // We are done with the effect chain at this point so let's clear the + // nextEffect pointers to assist with GC. If we have passive effects, we'll + // clear this in flushPassiveEffects. + nextEffect = firstEffect; + + while (nextEffect !== null) { + var nextNextEffect = nextEffect.nextEffect; + nextEffect.nextEffect = null; + + if (nextEffect.flags & Deletion) { + detachFiberAfterEffects(nextEffect); + } + + nextEffect = nextNextEffect; + } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -19601,9 +18709,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (includesSomeLane(remainingLanes, SyncLane)) { + if (remainingLanes === SyncLane) { + // Count the number of times the root synchronously re-renders without // finishing. If there are too many, it indicates an infinite update loop. - if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -19621,9 +18729,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var error = firstUncaughtError; + var _error3 = firstUncaughtError; firstUncaughtError = null; - throw error; + throw _error3; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -19639,14 +18747,149 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } +function commitBeforeMutationEffects() { + while (nextEffect !== null) { + var current = nextEffect.alternate; + + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + if ((nextEffect.flags & Deletion) !== NoFlags) { + if (doesFiberContain(nextEffect, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } + } else { + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + nextEffect.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } + } + } + + var flags = nextEffect.flags; + + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(nextEffect); + commitBeforeMutationLifeCycles(current, nextEffect); + resetCurrentFiber(); + } + + if ((flags & Passive) !== NoFlags) { + // If there are passive effects, schedule a callback to flush at + // the earliest opportunity. + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } + } + + nextEffect = nextEffect.nextEffect; + } +} + +function commitMutationEffects(root, renderPriorityLevel) { + // TODO: Should probably move the bulk of this function to commitWork. + while (nextEffect !== null) { + setCurrentFiber(nextEffect); + var flags = nextEffect.flags; + + if (flags & Ref) { + var current = nextEffect.alternate; + + if (current !== null) { + commitDetachRef(current); + } + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. + + var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); + + switch (primaryFlags) { + case Placement: { + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + nextEffect.flags &= ~Placement; + break; + } + + case PlacementAndUpdate: { + // inserted, before any life-cycles like componentDidMount gets called. + + nextEffect.flags &= ~Placement; // Update + + var _current = nextEffect.alternate; + commitWork(_current, nextEffect); + break; + } + + case Hydrating: { + nextEffect.flags &= ~Hydrating; + break; + } + + case HydratingAndUpdate: { + nextEffect.flags &= ~Hydrating; // Update + + var _current2 = nextEffect.alternate; + commitWork(_current2, nextEffect); + break; + } + + case Update: { + var _current3 = nextEffect.alternate; + commitWork(_current3, nextEffect); + break; + } + + case Deletion: { + commitDeletion(root, nextEffect); + break; + } + } + + resetCurrentFiber(); + nextEffect = nextEffect.nextEffect; + } +} + +function commitLayoutEffects(root, committedLanes) { + while (nextEffect !== null) { + setCurrentFiber(nextEffect); + var flags = nextEffect.flags; + + if (flags & (Update | Callback)) { + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); + } + + { + if (flags & Ref) { + commitAttachRef(nextEffect); + } + } + + resetCurrentFiber(); + nextEffect = nextEffect.nextEffect; + } +} + function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority) { + if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority - ? NormalPriority + pendingPassiveEffectsRenderPriority > NormalPriority$1 + ? NormalPriority$1 : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority; + pendingPassiveEffectsRenderPriority = NoPriority$1; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -19655,6 +18898,42 @@ function flushPassiveEffects() { return false; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + + { + fiber.flags |= PassiveUnmountPendingDev; + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.flags |= PassiveUnmountPendingDev; + } + } + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } +} + +function invokePassiveEffectCreate(effect) { + var create = effect.create; + effect.destroy = create(); +} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -19676,9 +18955,97 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - commitPassiveUnmountEffects(root.current); - commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called + // before ANY passive effect create functions are called. + // Otherwise effects in sibling components might interfere with each other. + // e.g. a destroy function in one component may unintentionally override a ref + // value set by a create function in another component. + // Layout effects have the same constraint. + // First pass: Destroy stale passive effects. + + var unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + + for (var i = 0; i < unmountEffects.length; i += 2) { + var _effect = unmountEffects[i]; + var fiber = unmountEffects[i + 1]; + var destroy = _effect.destroy; + _effect.destroy = undefined; + + { + fiber.flags &= ~PassiveUnmountPendingDev; + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; + } + } + + if (typeof destroy === "function") { + { + setCurrentFiber(fiber); + + { + invokeGuardedCallback(null, destroy, null); + } + + if (hasCaughtError()) { + if (!(fiber !== null)) { + throw Error("Should be working on an effect."); + } + + var error = clearCaughtError(); + captureCommitPhaseError(fiber, error); + } + + resetCurrentFiber(); + } + } + } // Second pass: Create new passive effects. + + var mountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + + for (var _i = 0; _i < mountEffects.length; _i += 2) { + var _effect2 = mountEffects[_i]; + var _fiber = mountEffects[_i + 1]; + + { + setCurrentFiber(_fiber); + + { + invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); + } + + if (hasCaughtError()) { + if (!(_fiber !== null)) { + throw Error("Should be working on an effect."); + } + + var _error4 = clearCaughtError(); + + captureCommitPhaseError(_fiber, _error4); + } + + resetCurrentFiber(); + } + } // Note: This currently assumes there are no passive effects on the root fiber + // because the root is not part of its own effect list. + // This could change in the future. + + var effect = root.current.firstEffect; + + while (effect !== null) { + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + + if (effect.flags & Deletion) { + detachFiberAfterEffects(effect); + } + + effect = nextNextEffect; + } { popInteractions(prevInteractions); @@ -19735,23 +19102,19 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { +function captureCommitPhaseError(sourceFiber, error) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); return; } - var fiber = null; - - { - fiber = sourceFiber.return; - } + var fiber = sourceFiber.return; while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -19762,7 +19125,7 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error$1, sourceFiber); + var errorInfo = createCapturedValue(error, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -19772,6 +19135,24 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); + } else { + // This component has already been unmounted. + // We can't schedule any follow up work for the root because the fiber is already unmounted, + // but we can still call the log-only boundary so the error isn't swallowed. + // + // TODO This is only a temporary bandaid for the old reconciler fork. + // We can delete this special case once the new fork is merged. + if ( + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance) + ) { + try { + instance.componentDidCatch(error, errorInfo); + } catch (errorToIgnore) { + // TODO Ignore this error? Rethrow it? + // This is kind of an edge case. + } + } } return; @@ -19780,22 +19161,6 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { fiber = fiber.return; } - - { - // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning - // will fire for errors that are thrown by destroy functions inside deleted - // trees. What it should instead do is propagate the error to the parent of - // the deleted tree. In the meantime, do not add this warning to the - // allowlist; this is only for our internal use. - error( - "Internal React error: Attempted to capture a commit phase error " + - "inside a detached tree. This indicates a bug in React. Likely " + - "causes include deleting the same fiber more than once, committing an " + - "already-finished tree, or an inconsistent return pointer.\n\n" + - "Error message:\n\n%s", - error$1 - ); - } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -19848,8 +19213,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { - // TODO: Assign this to `suspenseState.retryLane`? to avoid - // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -20018,29 +19381,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } - - if ((fiber.flags & PassiveStatic) !== NoFlags) { - var updateQueue = fiber.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - if (effect.destroy !== undefined) { - if ((effect.tag & Passive$1) !== NoFlags$1) { - return; - } - } + } // If there are pending passive effects unmounts for this Fiber, + // we can assume that they would have prevented this update. - effect = effect.next; - } while (effect !== firstEffect); - } - } + if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { + return; } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -20128,23 +19473,14 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); - - if ( - typeof replayError === "object" && - replayError !== null && - replayError._suppressLogging && - typeof originalError === "object" && - originalError !== null && - !originalError._suppressLogging - ) { - // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. - originalError._suppressLogging = true; - } - } // We always throw the original error in case the second render pass is not idempotent. - // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. + var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. + // Rethrow this error instead of the original one. - throw originalError; + throw replayError; + } else { + // This branch is reachable if the render phase is impure. + throw originalError; + } } }; } @@ -20330,7 +19666,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } @@ -20352,7 +19688,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } finally { @@ -20374,7 +19710,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } @@ -20393,6 +19729,11 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; +function detachFiberAfterEffects(fiber) { + fiber.sibling = null; + fiber.stateNode = null; +} + var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -20869,8 +20210,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.subtreeFlags = NoFlags; - this.deletions = null; + this.nextEffect = null; + this.firstEffect = null; + this.lastEffect = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -20997,10 +20339,11 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effects are no longer valid. + workInProgress.flags = NoFlags; // The effect list is no longer valid. - workInProgress.subtreeFlags = NoFlags; - workInProgress.deletions = null; + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -21010,10 +20353,8 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } // Reset all effects except static ones. - // Static effects are not specific to a render. + } - workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -21070,10 +20411,13 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect flags but keep any Placement tags, since that's something + // Reset the effect tag but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. + workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -21081,7 +20425,6 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; - workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -21098,12 +20441,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in - // `createWorkInProgress`. Nothing reads this until the complete phase, - // currently, but it might in the future, and we should be consistent. - - workInProgress.subtreeFlags = current.subtreeFlags; - workInProgress.deletions = null; + workInProgress.child = current.child; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -21130,33 +20468,13 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag, strictModeLevelOverride) { +function createHostRootFiber(tag) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode; - - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { - { - mode |= StrictLegacyMode; - } - } + mode = ConcurrentMode | BlockingMode | StrictMode; } else if (tag === BlockingRoot) { - mode = BlockingMode; - - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { - { - mode |= StrictLegacyMode; - } - } + mode = BlockingMode | StrictMode; } else { mode = NoMode; } @@ -21207,16 +20525,8 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. - - var level = - pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. - // It is explicitly not supported to lower a mode with nesting, only to increase it. - - if (level >= 1) { - mode |= StrictLegacyMode; - } - + fiberTag = Mode; + mode |= StrictMode; break; case REACT_PROFILER_TYPE: @@ -21238,10 +20548,6 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough - case REACT_CACHE_TYPE: - - // eslint-disable-next-line no-fallthrough - default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -21470,8 +20776,9 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.subtreeFlags = source.subtreeFlags; - target.deletions = source.deletions; + target.nextEffect = source.nextEffect; + target.firstEffect = source.firstEffect; + target.lastEffect = source.lastEffect; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -21538,27 +20845,13 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride -) { +function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - - { - var _initialState = { - element: null - }; - uninitializedFiber.memoizedState = _initialState; - } - initializeUpdateQueue(uninitializedFiber); return root; } @@ -21632,7 +20925,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictLegacyMode) { + if (hostFiber.mode & StrictMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -21642,7 +20935,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictLegacyMode) { + if (fiber.mode & StrictMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -21681,20 +20974,8 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride -) { - return createFiberRoot( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride - ); +function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { { @@ -21758,12 +21039,7 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - var root = scheduleUpdateOnFiber(current$1, lane, eventTime); - - if (root !== null) { - entangleTransitions(root, current$1, lane); - } - + scheduleUpdateOnFiber(current$1, lane, eventTime); return lane; } function getPublicRootInstance(container) { @@ -22303,15 +21579,13 @@ function findHostInstance_DEPRECATED(componentOrHandle) { if (componentOrHandle == null) { return null; - } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + } if (componentOrHandle._nativeTag) { - // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle; - } // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN + } if (componentOrHandle.canonical && componentOrHandle.canonical._nativeTag) { - // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN return componentOrHandle.canonical; } @@ -22453,12 +21727,11 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false, null, null); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN - + updateContainer(element, root, null, callback); return getPublicRootInstance(root); } @@ -22503,8 +21776,8 @@ exports.createPortal = createPortal$1; exports.dispatchCommand = dispatchCommand; exports.findHostInstance_DEPRECATED = findHostInstance_DEPRECATED; exports.findNodeHandle = findNodeHandle; -exports.render = render; exports.sendAccessibilityEvent = sendAccessibilityEvent; +exports.render = render; exports.stopSurface = stopSurface; exports.unmountComponentAtNode = unmountComponentAtNode; diff --git a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index dc0d1975d80703..035c6c10c7b3e8 100644 --- a/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_210 = { +var injectedNamesToPlugins$jscomp$inline_219 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_210 = { } } }, - isOrderingDirty$jscomp$inline_211 = !1, - pluginName$jscomp$inline_212; -for (pluginName$jscomp$inline_212 in injectedNamesToPlugins$jscomp$inline_210) + isOrderingDirty$jscomp$inline_220 = !1, + pluginName$jscomp$inline_221; +for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) if ( - injectedNamesToPlugins$jscomp$inline_210.hasOwnProperty( - pluginName$jscomp$inline_212 + injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( + pluginName$jscomp$inline_221 ) ) { - var pluginModule$jscomp$inline_213 = - injectedNamesToPlugins$jscomp$inline_210[pluginName$jscomp$inline_212]; + var pluginModule$jscomp$inline_222 = + injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_212) || - namesToPlugins[pluginName$jscomp$inline_212] !== - pluginModule$jscomp$inline_213 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || + namesToPlugins[pluginName$jscomp$inline_221] !== + pluginModule$jscomp$inline_222 ) { - if (namesToPlugins[pluginName$jscomp$inline_212]) + if (namesToPlugins[pluginName$jscomp$inline_221]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_212 + + pluginName$jscomp$inline_221 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_212 - ] = pluginModule$jscomp$inline_213; - isOrderingDirty$jscomp$inline_211 = !0; + pluginName$jscomp$inline_221 + ] = pluginModule$jscomp$inline_222; + isOrderingDirty$jscomp$inline_220 = !0; } } -isOrderingDirty$jscomp$inline_211 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -996,11 +996,7 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - (from || to).stateNode.canonical._internalInstanceHandle - ? (from && - nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), - to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) - : null !== to + null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1024,8 +1020,7 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131, - REACT_CACHE_TYPE = 60132; + REACT_LEGACY_HIDDEN_TYPE = 60131; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1044,7 +1039,6 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1071,8 +1065,6 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - case REACT_CACHE_TYPE: - return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1106,7 +1098,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 2050) && (nearestMounted = node.return), + 0 !== (node.flags & 1026) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1194,14 +1186,19 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; -} -function findCurrentHostFiberImpl(node) { - if (5 === node.tag || 6 === node.tag) return node; - for (node = node.child; null !== node; ) { - var match = findCurrentHostFiberImpl(node); - if (null !== match) return match; - node = node.sibling; + if (!parent) return null; + for (var node = parent; ; ) { + if (5 === node.tag || 6 === node.tag) return node; + if (node.child) (node.child.return = node), (node = node.child); + else { + if (node === parent) break; + for (; !node.sibling; ) { + if (!node.return || node.return === parent) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } return null; } @@ -1528,328 +1525,6 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs = Scheduler_now(), - now = - 1e4 > initialTimeMs - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var nextTransitionLane = 512, - nextRetryLane = 8388608, - return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - switch (lanes & -lanes) { - case 1: - return (return_highestLanePriority = 15), 1; - case 2: - return (return_highestLanePriority = 14), 2; - case 4: - return (return_highestLanePriority = 13), 4; - case 8: - return (return_highestLanePriority = 12), 8; - case 16: - return (return_highestLanePriority = 11), 16; - case 32: - return (return_highestLanePriority = 10), 32; - case 64: - return (return_highestLanePriority = 9), 64; - case 128: - return (return_highestLanePriority = 8), 128; - case 256: - return (return_highestLanePriority = 7), 256; - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - return (return_highestLanePriority = 6), lanes & 8388096; - case 8388608: - case 16777216: - case 33554432: - case 67108864: - return (return_highestLanePriority = 5), lanes & 125829120; - case 134217728: - return (return_highestLanePriority = 4), 134217728; - case 268435456: - return (return_highestLanePriority = 3), 268435456; - case 536870912: - return (return_highestLanePriority = 2), 536870912; - case 1073741824: - return (return_highestLanePriority = 1), 1073741824; - default: - return (return_highestLanePriority = 8), lanes; - } -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - 0 !== expiredLanes - ? ((nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15)) - : ((expiredLanes = pendingLanes & 268435455), - 0 !== expiredLanes - ? ((pendingLanes = expiredLanes & ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))); - if (0 === nextLanes) return 0; - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - suspendedLanes = return_highestLanePriority; - if ( - nextLanePriority <= suspendedLanes || - (8 === nextLanePriority && 6 === suspendedLanes) - ) - return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (nextLanePriority = 31 - clz32(wipLanes)), - (suspendedLanes = 1 << nextLanePriority), - (nextLanes |= root[nextLanePriority]), - (wipLanes &= ~suspendedLanes); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return 8; - case 10: - return 32; - case 8: - return 128; - case 2: - return 536870912; - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - remainingLanes = root.entanglements; - var eventTimes = root.eventTimes; - for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { - var index$7 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$7; - remainingLanes[index$7] = 0; - eventTimes[index$7] = -1; - root[index$7] = -1; - noLongerPendingLanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index$8 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$8; - (lane & entangledLanes) | (root[index$8] & entangledLanes) && - (root[index$8] |= entangledLanes); - rootEntangledLanes &= ~lane; - } -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_now$1 = Scheduler.unstable_now; -Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -2065,17 +1740,296 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null; -function onCommitRoot(root) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - void 0, - 128 === (root.current.flags & 128) + injectedHook = null, + Scheduler_now = Scheduler.unstable_now; +Scheduler_now(); +var return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; + if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; + if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; + var inputDiscreteLanes = 24 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 12), inputDiscreteLanes; + if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; + inputDiscreteLanes = 192 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 10), inputDiscreteLanes; + if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; + inputDiscreteLanes = 3584 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 8), inputDiscreteLanes; + if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; + inputDiscreteLanes = 4186112 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 6), inputDiscreteLanes; + inputDiscreteLanes = 62914560 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 5), inputDiscreteLanes; + if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; + if (0 !== (lanes & 134217728)) + return (return_highestLanePriority = 3), 134217728; + inputDiscreteLanes = 805306368 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 2), inputDiscreteLanes; + if (0 !== (1073741824 & lanes)) + return (return_highestLanePriority = 1), 1073741824; + return_highestLanePriority = 8; + return lanes; +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." ); - } catch (err) {} + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + if (0 !== expiredLanes) + (nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15); + else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { + var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority))); + } else + (expiredLanes = pendingLanes & ~suspendedLanes), + 0 !== expiredLanes + ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)); + if (0 === nextLanes) return 0; + nextLanes = 31 - clz32(nextLanes); + nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + if (nextLanePriority <= return_highestLanePriority) return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (nextLanePriority = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~nextLanePriority); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority, wipLanes) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return ( + (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority + ); + case 10: + return ( + (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority + ); + case 8: + return ( + (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), + 0 === lanePriority && + ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), + 0 === lanePriority && (lanePriority = 512)), + lanePriority + ); + case 2: + return ( + (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), + 0 === wipLanes && (wipLanes = 268435456), + wipLanes + ); + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + var higherPriorityLanes = updateLane - 1; + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + fakeCallbackNode = {}, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs$1 = Scheduler_now$1(), + now = + 1e4 > initialTimeMs$1 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2143,10 +2097,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(context) { +function popProvider(providerFiber) { var currentValue = valueCursor.current; pop(valueCursor); - context._currentValue2 = currentValue; + providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2197,14 +2151,13 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var interleavedQueues = null, - hasForceUpdate = !1; +var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null, interleaved: null, lanes: 0 }, + shared: { pending: null }, effects: null }; } @@ -2230,32 +2183,14 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - null !== updateQueue && - ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && 0 !== (fiber.mode & 1) - ? ((fiber = updateQueue.interleaved), - null === fiber - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [updateQueue]) - : interleavedQueues.push(updateQueue)) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.interleaved = update)) - : ((fiber = updateQueue.pending), - null === fiber - ? (update.next = update) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.pending = update))); -} -function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2324,110 +2259,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue + if (null !== current) { + current = current.updateQueue; + var currentLastBaseUpdate = current.lastBaseUpdate; + currentLastBaseUpdate !== lastBaseUpdate && + (null === currentLastBaseUpdate ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); + : (currentLastBaseUpdate.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate)); + } } if (null !== firstBaseUpdate) { - var newState = queue.baseState; + currentLastBaseUpdate = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; do { - var updateLane = pendingQueue.lane, - updateEventTime = pendingQueue.eventTime; - if ((renderLanes & updateLane) === updateLane) { + pendingQueue = firstBaseUpdate.lane; + var updateEventTime = firstBaseUpdate.eventTime; + if ((renderLanes & pendingQueue) === pendingQueue) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = pendingQueue; - updateLane = props; + update = firstBaseUpdate; + pendingQueue = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - newState = workInProgress.call( + currentLastBaseUpdate = workInProgress.call( updateEventTime, - newState, - updateLane + currentLastBaseUpdate, + pendingQueue ); break a; } - newState = workInProgress; + currentLastBaseUpdate = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -16385) | 128; + workInProgress.flags = (workInProgress.flags & -8193) | 64; case 0: workInProgress = update.payload; - updateLane = + pendingQueue = "function" === typeof workInProgress - ? workInProgress.call(updateEventTime, newState, updateLane) + ? workInProgress.call( + updateEventTime, + currentLastBaseUpdate, + pendingQueue + ) : workInProgress; - if (null === updateLane || void 0 === updateLane) break a; - newState = Object.assign({}, newState, updateLane); + if (null === pendingQueue || void 0 === pendingQueue) break a; + currentLastBaseUpdate = Object.assign( + {}, + currentLastBaseUpdate, + pendingQueue + ); break a; case 2: hasForceUpdate = !0; } } - null !== pendingQueue.callback && - ((workInProgress$jscomp$0.flags |= 64), - (updateLane = queue.effects), - null === updateLane - ? (queue.effects = [pendingQueue]) - : updateLane.push(pendingQueue)); + null !== firstBaseUpdate.callback && + ((workInProgress$jscomp$0.flags |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [firstBaseUpdate]) + : pendingQueue.push(firstBaseUpdate)); } else (updateEventTime = { eventTime: updateEventTime, - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + lane: pendingQueue, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = newState)) + (lastPendingUpdate = currentLastBaseUpdate)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) + (lastBaseUpdate |= pendingQueue); + firstBaseUpdate = firstBaseUpdate.next; + if (null === firstBaseUpdate) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (updateLane = pendingQueue), - (pendingQueue = updateLane.next), - (updateLane.next = null), - (queue.lastBaseUpdate = updateLane), + (firstBaseUpdate = pendingQueue.next), + (pendingQueue.next = null), + (queue.lastBaseUpdate = pendingQueue), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = newState); + null === current && (lastPendingUpdate = currentLastBaseUpdate); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; - props = queue.shared.interleaved; - if (null !== props) { - queue = props; - do (lastBaseUpdate |= queue.lane), (queue = queue.next); - while (queue !== props); - } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = newState; + workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2483,8 +2419,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2495,8 +2430,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2506,8 +2440,7 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - callback = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== callback && entangleTransitions(callback, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); } }; function checkShouldComponentUpdate( @@ -2655,22 +2588,24 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( + throw Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber + ("[object Object]" === Object.prototype.toString.call(newChild) ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + + : newChild) + "). If you meant to render a collection of children, use an array instead." - )); + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) - : deletions.push(childToDelete); + var last = returnFiber.lastEffect; + null !== last + ? ((last.nextEffect = childToDelete), + (returnFiber.lastEffect = childToDelete)) + : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); + childToDelete.nextEffect = null; + childToDelete.flags = 8; } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2702,16 +2637,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags |= 2), lastPlacedIndex) + ? ((newFiber.flags = 2), lastPlacedIndex) : newIndex ); - newFiber.flags |= 2; + newFiber.flags = 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags |= 2); + (newFiber.flags = 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2726,16 +2661,7 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - if (null !== current && current.elementType === elementType) + if (null !== current && current.elementType === element.type) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2849,7 +2775,15 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? updateElement(returnFiber, oldFiber, newChild, lanes) + ? newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ) + : updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2884,7 +2818,15 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - updateElement(returnFiber, existingChildren, newChild, lanes) + newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + existingChildren, + newChild.props.children, + lanes, + newChild.key + ) + : updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3079,49 +3021,54 @@ function ChildReconciler(shouldTrackSideEffects) { null === newChild.key; isUnkeyedTopLevelFragment && (newChild = newChild.props.children); var isObject = "object" === typeof newChild && null !== newChild; - if (isObject) - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - a: { - isObject = newChild.key; - for ( - isUnkeyedTopLevelFragment = currentFirstChild; - null !== isUnkeyedTopLevelFragment; - - ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { - if (7 === isUnkeyedTopLevelFragment.tag) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; + if (isObject) + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: + a: { + isObject = newChild.key; + for ( + isUnkeyedTopLevelFragment = currentFirstChild; + null !== isUnkeyedTopLevelFragment; + + ) { + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3299,7 +3246,7 @@ function findFirstSuspended(row) { 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; + if (0 !== (node.flags & 64)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3451,11 +3398,10 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - pendingQueue = baseQueue.next; + baseQueue = baseQueue.next; current = current.baseState; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = pendingQueue; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3480,33 +3426,22 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (baseFirst = current)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== pendingQueue); + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (baseFirst = current) - : (newBaseQueueLast.next = newBaseQueueFirst); + ? (pendingQueue = current) + : (newBaseQueueLast.next = baseFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = baseFirst; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } - reducer = queue.interleaved; - if (null !== reducer) { - baseQueue = reducer; - do - (pendingQueue = baseQueue.lane), - (currentlyRenderingFiber$1.lanes |= pendingQueue), - (workInProgressRootSkippedLanes |= pendingQueue), - (baseQueue = baseQueue.next); - while (baseQueue !== reducer); - } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3546,7 +3481,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3576,13 +3511,25 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - objectIs(version, maybeNewVersion) || - ((maybeNewVersion = getSnapshot(source._source)), + if (!objectIs(version, maybeNewVersion)) { + maybeNewVersion = getSnapshot(source._source); objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), - markRootEntangled(root, root.mutableReadLanes)); + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); + maybeNewVersion = root.mutableReadLanes; + root.entangledLanes |= maybeNewVersion; + for ( + var entanglements = root.entanglements, lanes = maybeNewVersion; + 0 < lanes; + + ) { + var index$11 = 31 - clz32(lanes), + lane = 1 << index$11; + entanglements[index$11] |= maybeNewVersion; + lanes &= ~lane; + } + } }, [getSnapshot, source, subscribe] ); @@ -3609,8 +3556,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3636,8 +3581,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3686,7 +3629,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); + pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3694,10 +3637,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(132096, 4, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(1024, 4, create, deps); + return updateEffectImpl(516, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3782,55 +3725,33 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - alternate = fiber.alternate; + pending = queue.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + queue.pending = update; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), - (lane = queue.pending), - null === lane - ? (update.next = update) - : ((update.next = lane.next), (lane.next = update)), - (queue.pending = update); + didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; else { - if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { - var interleaved = queue.interleaved; - null === interleaved - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [queue]) - : interleavedQueues.push(queue)) - : ((update.next = interleaved.next), (interleaved.next = update)); - queue.interleaved = update; - } else - (interleaved = queue.pending), - null === interleaved - ? (update.next = update) - : ((update.next = interleaved.next), (interleaved.next = update)), - (queue.pending = update); if ( 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.lanes) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.eagerReducer = alternate; + eagerState = pending(currentState, action); + update.eagerReducer = pending; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - update = scheduleUpdateOnFiber(fiber, lane, eventTime); - 0 !== (lane & 8388096) && - null !== update && - ((fiber = queue.lanes), - (fiber &= update.pendingLanes), - (lane |= fiber), - (queue.lanes = lane), - markRootEntangled(update, lane)); + scheduleUpdateOnFiber(fiber, lane, eventTime); } } var ContextOnlyDispatcher = { @@ -3887,8 +3808,6 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4064,7 +3983,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4140,15 +4059,14 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) + ) + if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); - 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); - } return updateFunctionComponent( current, workInProgress, @@ -4165,39 +4083,30 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 2)) - (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 + if (0 === (workInProgress.mode & 4)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes(workInProgress, renderLanes); + else if (0 !== (renderLanes & 1073741824)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes( + workInProgress, + null !== prevState ? prevState.baseLanes : renderLanes ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } + else + return ( + (current = + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { baseLanes: current }), + pushRenderLanes(workInProgress, current), + null + ); else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + pushRenderLanes(workInProgress, nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4207,7 +4116,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 256; + workInProgress.flags |= 128; } function updateFunctionComponent( current, @@ -4232,7 +4141,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4407,7 +4316,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 512)) + (workInProgress.flags |= 256)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4415,7 +4324,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4429,7 +4338,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (nextProps = !1)); } return finishClassComponent( @@ -4450,7 +4359,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 128); + var didCaptureError = 0 !== (workInProgress.flags & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4494,21 +4403,18 @@ function pushHostRootContext(workInProgress) { 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 = 0 !== (workInProgress.flags & 64)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -129)) + ? ((showFallback = !0), (workInProgress.flags &= -65)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4525,9 +4431,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4539,11 +4443,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 8388608), + (workInProgress.lanes = 33554432), current ); renderLanes = createFiberFromOffscreen( @@ -4569,11 +4471,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4600,11 +4499,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4627,7 +4523,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && null !== progressedPrimaryFragment + 0 === (mode & 2) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4660,14 +4556,13 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 2) && (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)); + ((current.nextEffect = null), + (current.flags = 8), + (workInProgress.firstEffect = workInProgress.lastEffect = current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4677,22 +4572,26 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child; + current = currentPrimaryChildFragment.sibling; + var primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) + (currentPrimaryChildFragment = primaryChildren.lastEffect), + null !== currentPrimaryChildFragment + ? ((workInProgress.firstEffect = primaryChildren.firstEffect), + (workInProgress.lastEffect = currentPrimaryChildFragment), + (currentPrimaryChildFragment.nextEffect = null)) + : (workInProgress.firstEffect = workInProgress.lastEffect = null)) + : (primaryChildren = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )); + null !== current + ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4717,7 +4616,8 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode + tailMode, + lastEffectBeforeRendering ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4727,14 +4627,16 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode)); + (renderState.tailMode = tailMode), + (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4743,9 +4645,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); else { - if (null !== current && 0 !== (current.flags & 128)) + if (null !== current && 0 !== (current.flags & 64)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4768,7 +4670,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4789,7 +4691,8 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "backwards": @@ -4811,11 +4714,19 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + initSuspenseListRenderState( + workInProgress, + !1, + null, + null, + void 0, + workInProgress.lastEffect + ); break; default: workInProgress.memoizedState = null; @@ -4825,33 +4736,25 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); 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; + if (0 !== (renderLanes & workInProgress.childLanes)) { + 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; } - return !0; + return null; } var appendAllChildren, updateHostContainer, @@ -4968,24 +4871,21 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(current, workInProgress) { +updateHostContainer = function(workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); + if (null !== workInProgress.firstEffect) { + var container = portalOrRoot.containerInfo, + newChildSet = createChildNodeSet(container); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(current, newChildSet); + completeRoot(container, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) + if ((current = null === workInProgress.firstEffect) && oldProps === newProps) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -5003,15 +4903,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (oldProps = type.node), + (recyclableInstance = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) + ? cloneNodeWithNewProps(recyclableInstance, newProps) + : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5047,40 +4947,16 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$62 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$62 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$62.sibling = null); + : (lastTailNode$64.sibling = null); } } -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags & 131072), - (subtreeFlags |= child$63.flags & 131072), - (child$63.return = completedWork), - (child$63 = child$63.sibling); - else - for (child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags), - (subtreeFlags |= child$63.flags), - (child$63.return = completedWork), - (child$63 = child$63.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -5094,81 +4970,76 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return bubbleProperties(workInProgress), null; + return null; case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 3: return ( - (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), + (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), + (workInProgress.flags |= 256), + updateHostContainer(workInProgress), null ); case 5: popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderLanes = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderLanes, newProps, - renderLanes + rootContainerInstance ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + current.ref !== workInProgress.ref && (workInProgress.flags |= 128); 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); + renderLanes = getViewConfigForType(renderLanes); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderLanes.validAttributes ); - renderLanes = createNode( + rootContainerInstance = createNode( current, - type.uiViewClassName, - renderLanes, + renderLanes.uiViewClassName, + rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - type, + renderLanes, newProps, workInProgress ); - current = { node: renderLanes, canonical: current }; + current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 256); + null !== workInProgress.ref && (workInProgress.flags |= 128); } - bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5184,25 +5055,25 @@ function completeWork(current, workInProgress, renderLanes) { "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); + rootContainerInstance = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - renderLanes, + rootContainerInstance, workInProgress ); } - bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) + if (0 !== (workInProgress.flags & 64)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) + rootContainerInstance = !1; + null !== current && + (rootContainerInstance = null !== current.memoizedState); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5217,92 +5088,82 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || + (0 === (workInProgressRootSkippedLanes & 134217727) && + 0 === (workInProgressRootUpdatedLanes & 134217727)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); return null; case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); + return popProvider(workInProgress), null; case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 19: pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.flags & 64); + updatePayload = newProps.rendering; if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) + (null !== current && 0 !== (current.flags & 64)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); + workInProgress.flags |= 64; + cutOffTailIfNeeded(newProps, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 131074), - (updatePayload = renderLanes.alternate), + (rootContainerInstance = newProps), + (renderLanes = current), + (rootContainerInstance.flags &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (updatePayload = rootContainerInstance.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 = updatePayload.subtreeFlags), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = + ? ((rootContainerInstance.childLanes = 0), + (rootContainerInstance.lanes = renderLanes), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.stateNode = null)) + : ((rootContainerInstance.childLanes = + updatePayload.childLanes), + (rootContainerInstance.lanes = updatePayload.lanes), + (rootContainerInstance.child = updatePayload.child), + (rootContainerInstance.memoizedProps = updatePayload.memoizedProps), - (renderLanes.memoizedState = + (rootContainerInstance.memoizedState = updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type + (rootContainerInstance.updateQueue = + updatePayload.updateQueue), + (rootContainerInstance.type = updatePayload.type), + (renderLanes = updatePayload.dependencies), + (rootContainerInstance.dependencies = + null === renderLanes ? null : { - lanes: type.lanes, - firstContext: type.firstContext + lanes: renderLanes.lanes, + firstContext: renderLanes.firstContext })), (newProps = newProps.sibling); push( @@ -5313,74 +5174,78 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== type.tail && + null !== newProps.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608)); + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432)); } else { - if (!newProps) + if (!rootContainerInstance) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 128), - (newProps = !0), + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && !updatePayload.alternate) ) - return bubbleProperties(workInProgress), null; + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - 2 * now() - type.renderingStartTime > + 2 * now() - newProps.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608)); - type.isBackwards + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432)); + newProps.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), + : ((current = newProps.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + (newProps.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; + return null !== newProps.tail + ? ((current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (workInProgress = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 + ), + current) + : null; case 22: case 23: return ( popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== renderLanes && + (null !== current.memoizedState) !== + (null !== workInProgress.memoizedState) && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), - (renderLanes && - 0 === (subtreeRenderLanes & 1073741824) && - 0 !== (workInProgress.mode & 2)) || - bubbleProperties(workInProgress), null ); } @@ -5395,8 +5260,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) + return flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) : null; case 3: popHostContainer(); @@ -5404,11 +5269,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 128)) + if (0 !== (flags & 64)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -16385) | 128; + workInProgress.flags = (flags & -8193) | 64; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5416,8 +5281,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) + flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) : null ); case 19: @@ -5425,12 +5290,10 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type._context), null; + return popProvider(workInProgress), null; case 22: case 23: return popRenderLanes(), null; - case 24: - return null; default: return null; } @@ -5509,161 +5372,152 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null; -function safelyDetachRef(current, nearestMountedAncestor) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; +function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, nearestMountedAncestor, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -var focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = null; - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) - doesFiberContain(firstChild[i], focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - firstChild = root.child; - if (0 !== (root.subtreeFlags & 516) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var current = root.alternate, - flags = root.flags; - if ( - !shouldFireAfterActiveInstanceBlur && - null !== focusedInstanceHandle - ) { - var JSCompiler_temp; - if ((JSCompiler_temp = 13 === root.tag)) - a: { - if (null !== current) { - var oldState = current.memoizedState; - if (null === oldState || null !== oldState.dehydrated) { - var newState = root.memoizedState; - JSCompiler_temp = - null !== newState && null === newState.dehydrated; - break a; - } - } - JSCompiler_temp = !1; - } - JSCompiler_temp && - doesFiberContain(root, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - } - if (0 !== (flags & 512)) - switch (root.tag) { - case 0: - case 11: - case 15: - break; - case 1: - if (null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState, - instance = root.stateNode, - snapshot = instance.getSnapshotBeforeUpdate( - root.elementType === root.type - ? prevProps - : resolveDefaultProps(root.type, prevProps), - prevState - ); - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - break; - case 3: - break; - case 5: - case 6: - case 4: - case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + return; + case 1: + if (finishedWork.flags & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } + return; + case 3: + return; + case 5: + case 6: + case 4: + case 17: + return; } - current = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - focusedInstanceHandle = null; - return current; + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor$jscomp$0 -) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; - if (void 0 !== destroy) { - var current = finishedWork, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); +function commitLifeCycles(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + if (3 === (finishedRoot.tag & 3)) { + var create$81 = finishedRoot.create; + finishedRoot.destroy = create$81(); } - } + finishedRoot = finishedRoot.next; + } while (finishedRoot !== current); } - effect = effect.next; - } while (effect !== updateQueue); - } -} -function commitHookEffectListMount(tag, finishedWork) { - finishedWork = finishedWork.updateQueue; - finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; - if (null !== finishedWork) { - var effect = (finishedWork = finishedWork.next); - do { - if ((effect.tag & tag) === tag) { - var create$80 = effect.create; - effect.destroy = create$80(); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + var _effect = finishedRoot; + create$81 = _effect.next; + _effect = _effect.tag; + 0 !== (_effect & 4) && + 0 !== (_effect & 1) && + (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), + enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); + finishedRoot = create$81; + } while (finishedRoot !== current); + } + return; + case 1: + finishedRoot = finishedWork.stateNode; + finishedWork.flags & 4 && + (null === current + ? finishedRoot.componentDidMount() + : ((create$81 = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current.memoizedProps + )), + finishedRoot.componentDidUpdate( + create$81, + current.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ))); + current = finishedWork.updateQueue; + null !== current && + commitUpdateQueue(finishedWork, current, finishedRoot); + return; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue(finishedWork, current, finishedRoot); } - effect = effect.next; - } while (effect !== finishedWork); + return; + case 5: + null === current && finishedWork.flags & 4 && shim(); + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + case 22: + case 23: + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function detachFiberAfterEffects(fiber) { +function detachFiberMutation(fiber) { fiber.alternate = null; fiber.child = null; - fiber.deletions = null; fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; + fiber.return = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5672,7 +5526,19 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedWork = current = current.next; + do { + if (3 === (finishedWork.tag & 3)) { + var destroy = finishedWork.destroy; + finishedWork.destroy = void 0; + void 0 !== destroy && destroy(); + } + finishedWork = finishedWork.next; + } while (finishedWork !== current); + } return; case 12: return; @@ -5693,286 +5559,39 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: + case 20: break a; case 3: case 4: break a; } throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } -} -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); - } -} -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - renderPriorityLevel = root.deletions; - if (null !== renderPriorityLevel) - for ( - firstChild = 0; - firstChild < renderPriorityLevel.length; - firstChild++ - ) { - var childToDelete = renderPriorityLevel[firstChild]; - try { - a: for (var node = childToDelete; ; ) { - var current = node; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = current.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - if (void 0 !== destroy && 0 !== (tag & 2)) { - _effect = current; - var nearestMountedAncestor = root; - try { - destroy(); - } catch (error) { - captureCommitPhaseError( - _effect, - nearestMountedAncestor, - error - ); - } - } - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(current, root); - var instance = current.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = current), - (_effect = instance), - (_effect.props = effect.memoizedProps), - (_effect.state = effect.memoizedState), - _effect.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(current, root, unmountError); - } - break; - case 5: - safelyDetachRef(current, root); - break; - case 4: - createChildNodeSet(current.stateNode.containerInfo); - } - if (null !== node.child) - (node.child.return = node), (node = node.child); - else { - if (node === childToDelete) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === childToDelete) - break a; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } - } - var alternate = childToDelete.alternate; - childToDelete.return = null; - null !== alternate && (alternate.return = null); - } catch (error) { - captureCommitPhaseError(childToDelete, root, error); - } - } - renderPriorityLevel = root.child; - if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) - (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var flags = root.flags; - if (flags & 256) { - var current$jscomp$0 = root.alternate; - if (null !== current$jscomp$0) { - var currentRef = current$jscomp$0.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 2054) { - case 2: - root.flags &= -3; - break; - case 6: - root.flags &= -3; - commitWork(root.alternate, root); - break; - case 2048: - root.flags &= -2049; - break; - case 2052: - root.flags &= -2049; - commitWork(root.alternate, root); - break; - case 4: - commitWork(root.alternate, root); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - renderPriorityLevel = root.sibling; - if (null !== renderPriorityLevel) { - renderPriorityLevel.return = root.return; - nextEffect = renderPriorityLevel; - break; - } - nextEffect = root.return; - } + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitLayoutEffects(finishedWork) { - for (nextEffect = finishedWork; null !== nextEffect; ) { - var fiber = nextEffect, - firstChild = fiber.child; - if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) - (firstChild.return = fiber), (nextEffect = firstChild); - else - for (fiber = finishedWork; null !== nextEffect; ) { - firstChild = nextEffect; - if (0 !== (firstChild.flags & 324)) { - var current = firstChild.alternate; - try { - if (0 !== (firstChild.flags & 68)) - switch (firstChild.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(3, firstChild); - break; - case 1: - var instance = firstChild.stateNode; - if (firstChild.flags & 4) - if (null === current) instance.componentDidMount(); - else { - var prevProps = - firstChild.elementType === firstChild.type - ? current.memoizedProps - : resolveDefaultProps( - firstChild.type, - current.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = firstChild.updateQueue; - null !== updateQueue && - commitUpdateQueue(firstChild, updateQueue, instance); - break; - case 3: - var updateQueue$81 = firstChild.updateQueue; - if (null !== updateQueue$81) { - current = null; - if (null !== firstChild.child) - switch (firstChild.child.tag) { - case 5: - current = firstChild.child.stateNode.canonical; - break; - case 1: - current = firstChild.child.stateNode; - } - commitUpdateQueue(firstChild, updateQueue$81, current); - } - break; - case 5: - null === current && firstChild.flags & 4 && shim(); - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 21: - case 22: - case 23: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - if (firstChild.flags & 256) { - current = void 0; - var ref = firstChild.ref; - if (null !== ref) { - var instance$jscomp$0 = firstChild.stateNode; - switch (firstChild.tag) { - case 5: - current = instance$jscomp$0.canonical; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - } catch (error) { - captureCommitPhaseError(firstChild, firstChild.return, error); - } - } - if (firstChild === fiber) { - nextEffect = null; - break; - } - current = firstChild.sibling; - if (null !== current) { - current.return = firstChild.return; - nextEffect = current; - break; - } - nextEffect = firstChild.return; - } +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); } } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + return null !== current && + ((current = current.memoizedState), + null === current || null !== current.dehydrated) + ? ((finishedWork = finishedWork.memoizedState), + null !== finishedWork && null === finishedWork.dehydrated) + : !1; +} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -5984,22 +5603,30 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, + workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, + mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, + pendingPassiveHookEffectsMount = [], + pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventTransitionLane = 0; + currentEventWipLanes = 0, + currentEventPendingLanes = 0, + focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6009,22 +5636,30 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 1)) return 1; - if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - if (0 !== ReactCurrentBatchConfig.transition) - return ( - 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), - (currentEventTransitionLane = fiber)), - currentEventTransitionLane - ); + if (0 === (fiber & 2)) return 1; + if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + 0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes); + if (0 !== ReactCurrentBatchConfig.transition) { + 0 !== currentEventPendingLanes && + (currentEventPendingLanes = + null !== mostRecentlyUpdatedRoot + ? mostRecentlyUpdatedRoot.pendingLanes + : 0); + fiber = currentEventWipLanes; + var lane = 4186112 & ~currentEventPendingLanes; + lane &= -lane; + 0 === lane && + ((fiber = 4186112 & ~fiber), + (lane = fiber & -fiber), + 0 === lane && (lane = 8192)); + return lane; + } fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12)) + ? (fiber = findUpdateLane(12, currentEventWipLanes)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber))); + (fiber = findUpdateLane(fiber, currentEventWipLanes))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6055,7 +5690,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - return fiber; + mostRecentlyUpdatedRoot = fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6103,42 +5738,45 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - 0 === suspendedLanes - ? (null !== existingCallbackNode && + if (0 === suspendedLanes) + null !== existingCallbackNode && + (existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)) - : root.callbackPriority !== currentTime && - (null != existingCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = null)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority( - currentTime - )), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))), - (root.callbackPriority = currentTime), - (root.callbackNode = existingCallbackNode)); -} -function performConcurrentWorkOnRoot(root, didTimeout) { + (root.callbackPriority = 0)); + else { + if (null !== existingCallbackNode) { + if (root.callbackPriority === currentTime) return; + existingCallbackNode !== fakeCallbackNode && + Scheduler_cancelCallback(existingCallbackNode); + } + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = fakeCallbackNode)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))); + root.callbackPriority = currentTime; + root.callbackNode = existingCallbackNode; + } +} +function performConcurrentWorkOnRoot(root) { currentEventTime = -1; - currentEventTransitionLane = 0; + currentEventPendingLanes = currentEventWipLanes = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6149,22 +5787,16 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - (root.expiredLanes |= lanes & root.pendingLanes), - ensureRootIsScheduled(root, now()), - null - ); - didTimeout = lanes; + var exitStatus = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== didTimeout + workInProgressRootRenderLanes !== exitStatus ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, didTimeout); + prepareFreshStack(root, exitStatus); do try { workLoopConcurrent(); @@ -6177,17 +5809,19 @@ function performConcurrentWorkOnRoot(root, didTimeout) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (didTimeout = 0) + ? (exitStatus = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); - if (0 !== didTimeout) { - 2 === didTimeout && + (exitStatus = workInProgressRootExitStatus)); + if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) + prepareFreshStack(root, 0); + else if (0 !== exitStatus) { + 2 === exitStatus && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); - if (1 === didTimeout) + 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (1 === exitStatus) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6195,7 +5829,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (didTimeout) { + switch (exitStatus) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6205,9 +5839,9 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 125829120) === lanes && - ((didTimeout = globalMostRecentFallbackTime + 500 - now()), - 10 < didTimeout) + (lanes & 62914560) === lanes && + ((exitStatus = globalMostRecentFallbackTime + 500 - now()), + 10 < exitStatus) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -6218,7 +5852,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - didTimeout + exitStatus ); break; } @@ -6226,12 +5860,12 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 8388096) === lanes) break; - didTimeout = root.eventTimes; + if ((lanes & 4186112) === lanes) break; + exitStatus = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); prevDispatcher = 1 << index$4; - index$4 = didTimeout[index$4]; + index$4 = exitStatus[index$4]; index$4 > prevExecutionContext && (prevExecutionContext = index$4); lanes &= ~prevDispatcher; } @@ -6278,9 +5912,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$6 = 31 - clz32(suspendedLanes), - lane = 1 << index$6; - root[index$6] = -1; + var index$9 = 31 - clz32(suspendedLanes), + lane = 1 << index$9; + root[index$9] = -1; suspendedLanes &= ~lane; } } @@ -6288,12 +5922,17 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes = + if ( root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ? workInProgressRootRenderLanes - : getNextLanes(root, 0); - var exitStatus = renderRootSync(root, lanes); + ) { + var lanes = workInProgressRootRenderLanes; + var exitStatus = renderRootSync(root, lanes); + 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && + ((lanes = getNextLanes(root, lanes)), + (exitStatus = renderRootSync(root, lanes))); + } else + (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6312,6 +5951,11 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } +function pushRenderLanes(fiber, lanes) { + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= lanes; + workInProgressRootIncludedLanes |= lanes; +} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6351,7 +5995,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type._context); + popProvider(interruptedWork); break; case 22: case 23: @@ -6361,29 +6005,10 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - if (null !== interleavedQueues) { - for (root = 0; root < interleavedQueues.length; root++) - if ( - ((lanes = interleavedQueues[root]), - (timeoutHandle = lanes.interleaved), - null !== timeoutHandle) - ) { - lanes.interleaved = null; - interruptedWork = timeoutHandle.next; - var lastPendingUpdate = lanes.pending; - if (null !== lastPendingUpdate) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = interruptedWork; - timeoutHandle.next = firstPendingUpdate; - } - lanes.pending = timeoutHandle; - } - interleavedQueues = null; - } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6419,18 +6044,15 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 8192; + sourceFiber.flags |= 4096; + sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value, - tag = sourceFiber.tag; - if ( - 0 === (sourceFiber.mode & 1) && - (0 === tag || 11 === tag || 15 === tag) - ) { + var wakeable = value; + if (0 === (sourceFiber.mode & 2)) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6441,15 +6063,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$75 = returnFiber; + workInProgress$76 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { - var nextState = workInProgress$75.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { + var nextState = workInProgress$76.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$75.memoizedProps; + var props = workInProgress$76.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6461,19 +6083,16 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$75.updateQueue; + var wakeables = workInProgress$76.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$75.updateQueue = updateQueue; + workInProgress$76.updateQueue = updateQueue; } else wakeables.add(wakeable); - if ( - 0 === (workInProgress$75.mode & 1) && - workInProgress$75 !== returnFiber - ) { - workInProgress$75.flags |= 128; - sourceFiber.flags |= 65536; - sourceFiber.flags &= -10053; + if (0 === (workInProgress$76.mode & 2)) { + workInProgress$76.flags |= 64; + sourceFiber.flags |= 32768; + sourceFiber.flags &= -5029; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6504,12 +6123,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$75.flags |= 16384; - workInProgress$75.lanes = thrownValue; + workInProgress$76.flags |= 8192; + workInProgress$76.lanes = thrownValue; break a; } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$76 = workInProgress$76.return; + } while (null !== workInProgress$76); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6518,47 +6137,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$75 = returnFiber; + workInProgress$76 = returnFiber; do { - switch (workInProgress$75.tag) { + switch (workInProgress$76.tag) { case 3: root = value; - workInProgress$75.flags |= 16384; + workInProgress$76.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$76 = createRootErrorUpdate( - workInProgress$75, + workInProgress$76.lanes |= thrownValue; + var update$77 = createRootErrorUpdate( + workInProgress$76, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$76); + enqueueCapturedUpdate(workInProgress$76, update$77); break a; case 1: root = value; - var ctor = workInProgress$75.type, - instance = workInProgress$75.stateNode; + var ctor = workInProgress$76.type, + instance = workInProgress$76.stateNode; if ( - 0 === (workInProgress$75.flags & 128) && + 0 === (workInProgress$76.flags & 64) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$75.flags |= 16384; + workInProgress$76.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$79 = createClassErrorUpdate( - workInProgress$75, + workInProgress$76.lanes |= thrownValue; + var update$80 = createClassErrorUpdate( + workInProgress$76, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$79); + enqueueCapturedUpdate(workInProgress$76, update$80); break a; } } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$76 = workInProgress$76.return; + } while (null !== workInProgress$76); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6619,25 +6238,47 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 8192)) { - if ( - ((current = completeWork(current, completedWork, subtreeRenderLanes)), - null !== current) - ) { + if (0 === (completedWork.flags & 4096)) { + current = completeWork(current, completedWork, subtreeRenderLanes); + if (null !== current) { workInProgress = current; return; } + current = completedWork; + if ( + (23 !== current.tag && 22 !== current.tag) || + null === current.memoizedState || + 0 !== (subtreeRenderLanes & 1073741824) || + 0 === (current.mode & 4) + ) { + for (var newChildLanes = 0, child = current.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (child = child.sibling); + current.childLanes = newChildLanes; + } + null !== unitOfWork && + 0 === (unitOfWork.flags & 4096) && + (null === unitOfWork.firstEffect && + (unitOfWork.firstEffect = completedWork.firstEffect), + null !== completedWork.lastEffect && + (null !== unitOfWork.lastEffect && + (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), + (unitOfWork.lastEffect = completedWork.lastEffect)), + 1 < completedWork.flags && + (null !== unitOfWork.lastEffect + ? (unitOfWork.lastEffect.nextEffect = completedWork) + : (unitOfWork.firstEffect = completedWork), + (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 8191; + current.flags &= 4095; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.flags |= 8192), - (unitOfWork.subtreeFlags = 0), - (unitOfWork.deletions = null)); + ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), + (unitOfWork.flags |= 4096)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6658,8 +6299,7 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; + var finishedWork = root.finishedWork; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6668,48 +6308,252 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - markRootFinished(root, remainingLanes); + var remainingLanes = finishedWork.lanes | finishedWork.childLanes, + remainingLanes$jscomp$0 = remainingLanes, + noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; + root.pendingLanes = remainingLanes$jscomp$0; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes$jscomp$0; + root.mutableReadLanes &= remainingLanes$jscomp$0; + root.entangledLanes &= remainingLanes$jscomp$0; + remainingLanes$jscomp$0 = root.entanglements; + for ( + var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; + 0 < noLongerPendingLanes; + + ) { + var index$10 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$10; + remainingLanes$jscomp$0[index$10] = 0; + eventTimes[index$10] = -1; + expirationTimes[index$10] = -1; + noLongerPendingLanes &= ~lane; + } null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 8) && + 0 === (remainingLanes & 24) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 1040) && - 0 === (finishedWork.flags & 1040)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - remainingLanes = 0 !== (finishedWork.flags & 8054); - 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes - ? ((remainingLanes = executionContext), - (executionContext |= 32), - (ReactCurrentOwner$2.current = null), - commitBeforeMutationEffects(root, finishedWork), - commitMutationEffects(root, renderPriorityLevel, finishedWork), - (root.current = finishedWork), - commitLayoutEffects(finishedWork, root, lanes), - requestPaint(), - (executionContext = remainingLanes)) - : (root.current = finishedWork); - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); + 1 < finishedWork.flags + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (remainingLanes = finishedWork.firstEffect)) + : (remainingLanes = finishedWork) + : (remainingLanes = finishedWork.firstEffect); + if (null !== remainingLanes) { + remainingLanes$jscomp$0 = executionContext; + executionContext |= 32; + focusedInstanceHandle = ReactCurrentOwner$2.current = null; + shouldFireAfterActiveInstanceBlur = !1; + nextEffect = remainingLanes; + do + try { + commitBeforeMutationEffects(); + } catch (error) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + focusedInstanceHandle = null; + nextEffect = remainingLanes; + do + try { + for (; null !== nextEffect; ) { + var flags = nextEffect.flags; + if (flags & 128) { + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 1038) { + case 2: + nextEffect.flags &= -3; + break; + case 6: + nextEffect.flags &= -3; + commitWork(nextEffect.alternate, nextEffect); + break; + case 1024: + nextEffect.flags &= -1025; + break; + case 1028: + nextEffect.flags &= -1025; + commitWork(nextEffect.alternate, nextEffect); + break; + case 4: + commitWork(nextEffect.alternate, nextEffect); + break; + case 8: + eventTimes = nextEffect; + a: for (noLongerPendingLanes = expirationTimes = eventTimes; ; ) { + index$10 = noLongerPendingLanes; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, index$10); + } catch (err) {} + switch (index$10.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = index$10.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next; + lane = firstEffect; + do { + var _effect2 = lane, + destroy = _effect2.destroy, + tag = _effect2.tag; + if (void 0 !== destroy) + if (0 !== (tag & 4)) + enqueuePendingPassiveHookEffectUnmount( + index$10, + lane + ); + else { + _effect2 = index$10; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect2, error); + } + } + lane = lane.next; + } while (lane !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(index$10); + var instance = index$10.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (lane = index$10), + (_effect2 = instance), + (_effect2.props = lane.memoizedProps), + (_effect2.state = lane.memoizedState), + _effect2.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(index$10, unmountError); + } + break; + case 5: + safelyDetachRef(index$10); + break; + case 4: + createChildNodeSet(index$10.stateNode.containerInfo); + } + if (null !== noLongerPendingLanes.child) + (noLongerPendingLanes.child.return = noLongerPendingLanes), + (noLongerPendingLanes = noLongerPendingLanes.child); + else { + if (noLongerPendingLanes === expirationTimes) break; + for (; null === noLongerPendingLanes.sibling; ) { + if ( + null === noLongerPendingLanes.return || + noLongerPendingLanes.return === expirationTimes + ) + break a; + noLongerPendingLanes = noLongerPendingLanes.return; + } + noLongerPendingLanes.sibling.return = + noLongerPendingLanes.return; + noLongerPendingLanes = noLongerPendingLanes.sibling; + } + } + var alternate = eventTimes.alternate; + detachFiberMutation(eventTimes); + null !== alternate && detachFiberMutation(alternate); + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$87) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$87); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + root.current = finishedWork; + nextEffect = remainingLanes; + do + try { + for (flags = root; null !== nextEffect; ) { + var flags$jscomp$0 = nextEffect.flags; + flags$jscomp$0 & 36 && + commitLifeCycles(flags, nextEffect.alternate, nextEffect); + if (flags$jscomp$0 & 128) { + current = void 0; + var ref = nextEffect.ref; + if (null !== ref) { + var instance$jscomp$0 = nextEffect.stateNode; + switch (nextEffect.tag) { + case 5: + current = instance$jscomp$0.canonical; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$88) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$88); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + nextEffect = null; + requestPaint(); + executionContext = remainingLanes$jscomp$0; + } else root.current = finishedWork; + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel); + else + for (nextEffect = remainingLanes; null !== nextEffect; ) + (renderPriorityLevel = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + nextEffect.flags & 8 && + ((flags$jscomp$0 = nextEffect), + (flags$jscomp$0.sibling = null), + (flags$jscomp$0.stateNode = null)), + (nextEffect = renderPriorityLevel); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 0 !== (remainingLanes & 1) + 1 === remainingLanes ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + finishedWork = finishedWork.stateNode; + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + finishedWork, + void 0, + 64 === (finishedWork.current.flags & 64) + ); + } catch (err) {} ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6720,6 +6564,30 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } +function commitBeforeMutationEffects() { + for (; null !== nextEffect; ) { + var current = nextEffect.alternate; + shouldFireAfterActiveInstanceBlur || + null === focusedInstanceHandle || + (0 !== (nextEffect.flags & 8) + ? doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0) + : 13 === nextEffect.tag && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0)); + var flags = nextEffect.flags; + 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); + 0 === (flags & 512) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + nextEffect = nextEffect.nextEffect; + } +} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6731,6 +6599,24 @@ function flushPassiveEffects() { } return !1; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6739,103 +6625,40 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - for (nextEffect = root.current; null !== nextEffect; ) { - var fiber = nextEffect, - child = fiber.child; - if (0 !== (nextEffect.flags & 16)) { - var deletions = fiber.deletions; - if (null !== deletions) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - for (nextEffect = fiberToDelete; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); - } - var child$jscomp$0 = fiber$jscomp$0.child; - if (null !== child$jscomp$0) - (child$jscomp$0.return = fiber$jscomp$0), - (nextEffect = child$jscomp$0); - else - for (; null !== nextEffect; ) { - fiber$jscomp$0 = nextEffect; - if (fiber$jscomp$0 === fiberToDelete) { - nextEffect = null; - break; - } - child$jscomp$0 = fiber$jscomp$0.sibling; - if (null !== child$jscomp$0) { - child$jscomp$0.return = fiber$jscomp$0.return; - nextEffect = child$jscomp$0; - break; - } - nextEffect = fiber$jscomp$0.return; - } - } - fiber$jscomp$0 = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); - null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); - } - nextEffect = fiber; + var unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + for (var i = 0; i < unmountEffects.length; i += 2) { + var effect$93 = unmountEffects[i], + fiber = unmountEffects[i + 1], + destroy = effect$93.destroy; + effect$93.destroy = void 0; + if ("function" === typeof destroy) + try { + destroy(); + } catch (error) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error); } + } + unmountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + for (i = 0; i < unmountEffects.length; i += 2) { + effect$93 = unmountEffects[i]; + fiber = unmountEffects[i + 1]; + try { + var create$97 = effect$93.create; + effect$93.destroy = create$97(); + } catch (error$98) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error$98); } - if (0 !== (fiber.subtreeFlags & 1040) && null !== child) - (child.return = fiber), (nextEffect = child); - else - a: for (; null !== nextEffect; ) { - fiber = nextEffect; - if (0 !== (fiber.flags & 1024)) - switch (fiber.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(5, fiber, fiber.return); - } - child = fiber.sibling; - if (null !== child) { - child.return = fiber.return; - nextEffect = child; - break a; - } - nextEffect = fiber.return; - } } - for (nextEffect = root = root.current; null !== nextEffect; ) - if ( - ((fiber = nextEffect), - (child = fiber.child), - 0 !== (fiber.subtreeFlags & 1040) && null !== child) - ) - (child.return = fiber), (nextEffect = child); - else - a: for (fiber = root; null !== nextEffect; ) { - child = nextEffect; - if (0 !== (child.flags & 1024)) - try { - switch (child.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(5, child); - } - } catch (error) { - captureCommitPhaseError(child, child.return, error); - } - if (child === fiber) { - nextEffect = null; - break a; - } - deletions = child.sibling; - if (null !== deletions) { - deletions.return = child.return; - nextEffect = deletions; - break a; - } - nextEffect = child.return; - } + for (create$97 = root.current.firstEffect; null !== create$97; ) + (root = create$97.nextEffect), + (create$97.nextEffect = null), + create$97.flags & 8 && + ((create$97.sibling = null), (create$97.stateNode = null)), + (create$97 = root); executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -6850,50 +6673,42 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { +function captureCommitPhaseError(sourceFiber, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for ( - nearestMountedAncestor = sourceFiber.return; - null !== nearestMountedAncestor; - - ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error - ); + for (var fiber = sourceFiber.return; null !== fiber; ) { + if (3 === fiber.tag) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); break; - } else if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; + } else if (1 === fiber.tag) { + var instance = fiber.stateNode; if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || + "function" === typeof fiber.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - sourceFiber = createClassErrorUpdate( - nearestMountedAncestor, - sourceFiber, - 1 - ); - enqueueUpdate(nearestMountedAncestor, sourceFiber); - sourceFiber = requestEventTime(); - nearestMountedAncestor = markUpdateLaneFromFiberToRoot( - nearestMountedAncestor, - 1 - ); - null !== nearestMountedAncestor && - (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); + var update = createClassErrorUpdate(fiber, sourceFiber, 1); + enqueueUpdate(fiber, update); + update = requestEventTime(); + fiber = markUpdateLaneFromFiberToRoot(fiber, 1); + if (null !== fiber) + markRootUpdated(fiber, 1, update), + ensureRootIsScheduled(fiber, update); + else if ( + "function" === typeof instance.componentDidCatch && + (null === legacyErrorBoundariesThatAlreadyFailed || + !legacyErrorBoundariesThatAlreadyFailed.has(instance)) + ) + try { + instance.componentDidCatch(error, sourceFiber); + } catch (errorToIgnore) {} break; } } - nearestMountedAncestor = nearestMountedAncestor.return; + fiber = fiber.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -6905,7 +6720,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 125829120) === + (workInProgressRootRenderLanes & 62914560) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -6918,13 +6733,14 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 1) + 0 === (wakeable & 2) ? (wakeable = 1) - : 0 === (wakeable & 2) + : 0 === (wakeable & 4) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : ((wakeable = nextRetryLane), - (nextRetryLane <<= 1), - 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); + : (0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes), + (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), + 0 === wakeable && (wakeable = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -6940,83 +6756,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; + else if (0 !== (renderLanes & updateLanes)) + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; 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( + 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.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateLanes; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( 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) + workInProgress = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); - } - return 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 & 64)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 64; + } + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); } - didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7028,22 +6839,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateLanes, 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; @@ -7053,8 +6864,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7065,9 +6876,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7079,28 +6890,28 @@ beginWork$1 = function(current, workInProgress, 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; + context = 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); + hasContext = context._init; + context = hasContext(context._payload); + workInProgress.type = context; + hasContext = workInProgress.tag = resolveLazyComponentTag(context); + current = resolveDefaultProps(context, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7109,7 +6920,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7118,7 +6929,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7127,8 +6938,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), + context, + resolveDefaultProps(context.type, current), updateLanes, renderLanes ); @@ -7136,7 +6947,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + context + ". Lazy element type must resolve to a class or function." ); } @@ -7144,32 +6955,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateFunctionComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateClassComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7180,18 +6991,19 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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; + updateLanes = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + updateLanes = workInProgress.memoizedState.element; + updateLanes === context ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7231,16 +7043,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateForwardRef( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7277,21 +7089,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = nextValue.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) { - var oldValue = getDerivedStateFromProps.value; - hasContext = objectIs(oldValue, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits(oldValue, hasContext) - : 1073741823) | 0; - if (0 === hasContext) { + hasContext = context.value; + var context$jscomp$0 = workInProgress.type._context; + push(valueCursor, context$jscomp$0._currentValue2); + context$jscomp$0._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) + if ( + ((context$jscomp$0 = getDerivedStateFromProps.value), + (hasContext = objectIs(context$jscomp$0, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits( + context$jscomp$0, + hasContext + ) + : 1073741823) | 0), + 0 === hasContext) + ) { if ( - getDerivedStateFromProps.children === nextValue.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7303,14 +7121,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7320,24 +7139,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - if (1 === oldValue.tag) { - dependency = createUpdate(-1, renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = oldValue.updateQueue; - if (null !== updateQueue) { - updateQueue = updateQueue.shared; - var pending = updateQueue.pending; - null === pending - ? (dependency.next = dependency) - : ((dependency.next = pending.next), - (pending.next = dependency)); - updateQueue.pending = dependency; - } - } - oldValue.lanes |= renderLanes; - dependency = oldValue.alternate; + 1 === context$jscomp$0.tag && + ((dependency = createUpdate( + -1, + renderLanes & -renderLanes + )), + (dependency.tag = 2), + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.lanes |= renderLanes; + dependency = context$jscomp$0.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath(oldValue.return, renderLanes); + scheduleWorkOnParentPath( + context$jscomp$0.return, + renderLanes + ); list.lanes |= renderLanes; break; } @@ -7345,16 +7160,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7362,21 +7177,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7384,28 +7198,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(context)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - nextValue, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( current, workInProgress, - nextValue, + context, hasContext, updateLanes, renderLanes @@ -7423,11 +7237,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7437,8 +7251,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, updateLanes, context), + mountClassInstance(workInProgress, updateLanes, context, renderLanes), finishClassComponent( null, workInProgress, @@ -7470,8 +7284,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.subtreeFlags = this.flags = 0; - this.deletions = null; + this.flags = 0; + this.lastEffect = this.firstEffect = this.nextEffect = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7509,9 +7323,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null)); - workInProgress.flags = current.flags & 131072; + (workInProgress.nextEffect = null), + (workInProgress.firstEffect = null), + (workInProgress.lastEffect = null)); workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7546,18 +7360,15 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 8; + mode |= 16; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 16); + mode |= 1; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7744,8 +7555,7 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - element = scheduleUpdateOnFiber(current, lane, eventTime); - null !== element && entangleTransitions(element, current, lane); + scheduleUpdateOnFiber(current, lane, eventTime); return lane; } function emptyFindFiberByHostInstance() { @@ -7777,10 +7587,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_914 = { + devToolsConfig$jscomp$inline_865 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.2", + version: "17.0.1-454c2211c", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -7795,11 +7605,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1178 = { - bundleType: devToolsConfig$jscomp$inline_914.bundleType, - version: devToolsConfig$jscomp$inline_914.version, - rendererPackageName: devToolsConfig$jscomp$inline_914.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_914.rendererConfig, +var internals$jscomp$inline_1054 = { + bundleType: devToolsConfig$jscomp$inline_865.bundleType, + version: devToolsConfig$jscomp$inline_865.version, + rendererPackageName: devToolsConfig$jscomp$inline_865.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_865.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -7814,7 +7624,7 @@ var internals$jscomp$inline_1178 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_914.findFiberByHostInstance || + devToolsConfig$jscomp$inline_865.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -7823,16 +7633,16 @@ var internals$jscomp$inline_1178 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1179 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1055 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1179.isDisabled && - hook$jscomp$inline_1179.supportsFiber + !hook$jscomp$inline_1055.isDisabled && + hook$jscomp$inline_1055.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1179.inject( - internals$jscomp$inline_1178 + (rendererID = hook$jscomp$inline_1055.inject( + internals$jscomp$inline_1054 )), - (injectedHook = hook$jscomp$inline_1179); + (injectedHook = hook$jscomp$inline_1055); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -7874,11 +7684,10 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var JSCompiler_inline_result = createFiber(3, null, null, 0); - root.current = JSCompiler_inline_result; - JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; - initializeUpdateQueue(JSCompiler_inline_result); + var uninitializedFiber = createFiber(3, null, null, 0); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 96243f376c9204..51f399468cdf57 100644 --- a/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_216 = { +var injectedNamesToPlugins$jscomp$inline_223 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ var injectedNamesToPlugins$jscomp$inline_216 = { } } }, - isOrderingDirty$jscomp$inline_217 = !1, - pluginName$jscomp$inline_218; -for (pluginName$jscomp$inline_218 in injectedNamesToPlugins$jscomp$inline_216) + isOrderingDirty$jscomp$inline_224 = !1, + pluginName$jscomp$inline_225; +for (pluginName$jscomp$inline_225 in injectedNamesToPlugins$jscomp$inline_223) if ( - injectedNamesToPlugins$jscomp$inline_216.hasOwnProperty( - pluginName$jscomp$inline_218 + injectedNamesToPlugins$jscomp$inline_223.hasOwnProperty( + pluginName$jscomp$inline_225 ) ) { - var pluginModule$jscomp$inline_219 = - injectedNamesToPlugins$jscomp$inline_216[pluginName$jscomp$inline_218]; + var pluginModule$jscomp$inline_226 = + injectedNamesToPlugins$jscomp$inline_223[pluginName$jscomp$inline_225]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_218) || - namesToPlugins[pluginName$jscomp$inline_218] !== - pluginModule$jscomp$inline_219 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_225) || + namesToPlugins[pluginName$jscomp$inline_225] !== + pluginModule$jscomp$inline_226 ) { - if (namesToPlugins[pluginName$jscomp$inline_218]) + if (namesToPlugins[pluginName$jscomp$inline_225]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_218 + + pluginName$jscomp$inline_225 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_218 - ] = pluginModule$jscomp$inline_219; - isOrderingDirty$jscomp$inline_217 = !0; + pluginName$jscomp$inline_225 + ] = pluginModule$jscomp$inline_226; + isOrderingDirty$jscomp$inline_224 = !0; } } -isOrderingDirty$jscomp$inline_217 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_224 && recomputePluginOrdering(); function getInstanceFromInstance(instanceHandle) { return instanceHandle; } @@ -997,11 +997,7 @@ getNodeFromInstance = function(inst) { }; ResponderEventPlugin.injection.injectGlobalResponderHandler({ onChange: function(from, to, blockNativeResponder) { - (from || to).stateNode.canonical._internalInstanceHandle - ? (from && - nativeFabricUIManager.setIsJSResponder(from.stateNode.node, !1), - to && nativeFabricUIManager.setIsJSResponder(to.stateNode.node, !0)) - : null !== to + null !== to ? ReactNativePrivateInterface.UIManager.setJSResponder( to.stateNode.canonical._nativeTag, blockNativeResponder @@ -1025,8 +1021,7 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131, - REACT_CACHE_TYPE = 60132; + REACT_LEGACY_HIDDEN_TYPE = 60131; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1045,7 +1040,6 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1072,8 +1066,6 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - case REACT_CACHE_TYPE: - return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1107,7 +1099,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 2050) && (nearestMounted = node.return), + 0 !== (node.flags & 1026) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1195,14 +1187,19 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; -} -function findCurrentHostFiberImpl(node) { - if (5 === node.tag || 6 === node.tag) return node; - for (node = node.child; null !== node; ) { - var match = findCurrentHostFiberImpl(node); - if (null !== match) return match; - node = node.sibling; + if (!parent) return null; + for (var node = parent; ; ) { + if (5 === node.tag || 6 === node.tag) return node; + if (node.child) (node.child.return = node), (node = node.child); + else { + if (node === parent) break; + for (; !node.sibling; ) { + if (!node.return || node.return === parent) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } return null; } @@ -1529,342 +1526,6 @@ function dispatchEvent(target, topLevelType, nativeEvent) { } }); } -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -var requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs = Scheduler_now(), - now = - 1e4 > initialTimeMs - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var nextTransitionLane = 512, - nextRetryLane = 8388608, - return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - switch (lanes & -lanes) { - case 1: - return (return_highestLanePriority = 15), 1; - case 2: - return (return_highestLanePriority = 14), 2; - case 4: - return (return_highestLanePriority = 13), 4; - case 8: - return (return_highestLanePriority = 12), 8; - case 16: - return (return_highestLanePriority = 11), 16; - case 32: - return (return_highestLanePriority = 10), 32; - case 64: - return (return_highestLanePriority = 9), 64; - case 128: - return (return_highestLanePriority = 8), 128; - case 256: - return (return_highestLanePriority = 7), 256; - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - return (return_highestLanePriority = 6), lanes & 8388096; - case 8388608: - case 16777216: - case 33554432: - case 67108864: - return (return_highestLanePriority = 5), lanes & 125829120; - case 134217728: - return (return_highestLanePriority = 4), 134217728; - case 268435456: - return (return_highestLanePriority = 3), 268435456; - case 536870912: - return (return_highestLanePriority = 2), 536870912; - case 1073741824: - return (return_highestLanePriority = 1), 1073741824; - default: - return (return_highestLanePriority = 8), lanes; - } -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - 0 !== expiredLanes - ? ((nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15)) - : ((expiredLanes = pendingLanes & 268435455), - 0 !== expiredLanes - ? ((pendingLanes = expiredLanes & ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))); - if (0 === nextLanes) return 0; - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - suspendedLanes = return_highestLanePriority; - if ( - nextLanePriority <= suspendedLanes || - (8 === nextLanePriority && 6 === suspendedLanes) - ) - return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (nextLanePriority = 31 - clz32(wipLanes)), - (suspendedLanes = 1 << nextLanePriority), - (nextLanes |= root[nextLanePriority]), - (wipLanes &= ~suspendedLanes); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return 8; - case 10: - return 32; - case 8: - return 128; - case 2: - return 536870912; - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - remainingLanes = root.entanglements; - var eventTimes = root.eventTimes; - for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { - var index$7 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$7; - remainingLanes[index$7] = 0; - eventTimes[index$7] = -1; - root[index$7] = -1; - noLongerPendingLanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index$8 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$8; - (lane & entangledLanes) | (root[index$8] & entangledLanes) && - (root[index$8] |= entangledLanes); - rootEntangledLanes &= ~lane; - } -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_now$1 = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now$1(); function shim() { throw Error( "The current renderer does not support mutation. This error is likely caused by a bug in React. Please file an issue." @@ -2081,17 +1742,310 @@ function invalidateContextProvider(workInProgress, type, didChange) { } var rendererID = null, injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function onCommitRoot(root, priorityLevel) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - 128 === (root.current.flags & 128) + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, + Scheduler_now = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now(); +var return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; + if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; + if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; + var inputDiscreteLanes = 24 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 12), inputDiscreteLanes; + if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; + inputDiscreteLanes = 192 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 10), inputDiscreteLanes; + if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; + inputDiscreteLanes = 3584 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 8), inputDiscreteLanes; + if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; + inputDiscreteLanes = 4186112 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 6), inputDiscreteLanes; + inputDiscreteLanes = 62914560 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 5), inputDiscreteLanes; + if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; + if (0 !== (lanes & 134217728)) + return (return_highestLanePriority = 3), 134217728; + inputDiscreteLanes = 805306368 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 2), inputDiscreteLanes; + if (0 !== (1073741824 & lanes)) + return (return_highestLanePriority = 1), 1073741824; + return_highestLanePriority = 8; + return lanes; +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." ); - } catch (err) {} + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + if (0 !== expiredLanes) + (nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15); + else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { + var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority))); + } else + (expiredLanes = pendingLanes & ~suspendedLanes), + 0 !== expiredLanes + ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)); + if (0 === nextLanes) return 0; + nextLanes = 31 - clz32(nextLanes); + nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + if (nextLanePriority <= return_highestLanePriority) return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (nextLanePriority = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~nextLanePriority); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority, wipLanes) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return ( + (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority + ); + case 10: + return ( + (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority + ); + case 8: + return ( + (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), + 0 === lanePriority && + ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), + 0 === lanePriority && (lanePriority = 512)), + lanePriority + ); + case 2: + return ( + (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), + 0 === wipLanes && (wipLanes = 268435456), + wipLanes + ); + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + var higherPriorityLanes = updateLane - 1; + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var fakeCallbackNode = {}, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs$1 = Scheduler_now$1(), + now = + 1e4 > initialTimeMs$1 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2159,10 +2113,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(context) { +function popProvider(providerFiber) { var currentValue = valueCursor.current; pop(valueCursor); - context._currentValue2 = currentValue; + providerFiber.type._context._currentValue2 = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2213,14 +2167,13 @@ function readContext(context, observedBits) { } return context._currentValue2; } -var interleavedQueues = null, - hasForceUpdate = !1; +var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null, interleaved: null, lanes: 0 }, + shared: { pending: null }, effects: null }; } @@ -2246,32 +2199,14 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - null !== updateQueue && - ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && 0 !== (fiber.mode & 1) - ? ((fiber = updateQueue.interleaved), - null === fiber - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [updateQueue]) - : interleavedQueues.push(updateQueue)) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.interleaved = update)) - : ((fiber = updateQueue.pending), - null === fiber - ? (update.next = update) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.pending = update))); -} -function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2340,110 +2275,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue + if (null !== current) { + current = current.updateQueue; + var currentLastBaseUpdate = current.lastBaseUpdate; + currentLastBaseUpdate !== lastBaseUpdate && + (null === currentLastBaseUpdate ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); + : (currentLastBaseUpdate.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate)); + } } if (null !== firstBaseUpdate) { - var newState = queue.baseState; + currentLastBaseUpdate = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; do { - var updateLane = pendingQueue.lane, - updateEventTime = pendingQueue.eventTime; - if ((renderLanes & updateLane) === updateLane) { + pendingQueue = firstBaseUpdate.lane; + var updateEventTime = firstBaseUpdate.eventTime; + if ((renderLanes & pendingQueue) === pendingQueue) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = pendingQueue; - updateLane = props; + update = firstBaseUpdate; + pendingQueue = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - newState = workInProgress.call( + currentLastBaseUpdate = workInProgress.call( updateEventTime, - newState, - updateLane + currentLastBaseUpdate, + pendingQueue ); break a; } - newState = workInProgress; + currentLastBaseUpdate = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -16385) | 128; + workInProgress.flags = (workInProgress.flags & -8193) | 64; case 0: workInProgress = update.payload; - updateLane = + pendingQueue = "function" === typeof workInProgress - ? workInProgress.call(updateEventTime, newState, updateLane) + ? workInProgress.call( + updateEventTime, + currentLastBaseUpdate, + pendingQueue + ) : workInProgress; - if (null === updateLane || void 0 === updateLane) break a; - newState = Object.assign({}, newState, updateLane); + if (null === pendingQueue || void 0 === pendingQueue) break a; + currentLastBaseUpdate = Object.assign( + {}, + currentLastBaseUpdate, + pendingQueue + ); break a; case 2: hasForceUpdate = !0; } } - null !== pendingQueue.callback && - ((workInProgress$jscomp$0.flags |= 64), - (updateLane = queue.effects), - null === updateLane - ? (queue.effects = [pendingQueue]) - : updateLane.push(pendingQueue)); + null !== firstBaseUpdate.callback && + ((workInProgress$jscomp$0.flags |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [firstBaseUpdate]) + : pendingQueue.push(firstBaseUpdate)); } else (updateEventTime = { eventTime: updateEventTime, - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + lane: pendingQueue, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = newState)) + (lastPendingUpdate = currentLastBaseUpdate)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) + (lastBaseUpdate |= pendingQueue); + firstBaseUpdate = firstBaseUpdate.next; + if (null === firstBaseUpdate) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (updateLane = pendingQueue), - (pendingQueue = updateLane.next), - (updateLane.next = null), - (queue.lastBaseUpdate = updateLane), + (firstBaseUpdate = pendingQueue.next), + (pendingQueue.next = null), + (queue.lastBaseUpdate = pendingQueue), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = newState); + null === current && (lastPendingUpdate = currentLastBaseUpdate); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; - props = queue.shared.interleaved; - if (null !== props) { - queue = props; - do (lastBaseUpdate |= queue.lane), (queue = queue.next); - while (queue !== props); - } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = newState; + workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2499,8 +2435,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2511,8 +2446,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2522,8 +2456,7 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - callback = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== callback && entangleTransitions(callback, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); } }; function checkShouldComponentUpdate( @@ -2671,22 +2604,24 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( + throw Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber + ("[object Object]" === Object.prototype.toString.call(newChild) ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + + : newChild) + "). If you meant to render a collection of children, use an array instead." - )); + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) - : deletions.push(childToDelete); + var last = returnFiber.lastEffect; + null !== last + ? ((last.nextEffect = childToDelete), + (returnFiber.lastEffect = childToDelete)) + : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); + childToDelete.nextEffect = null; + childToDelete.flags = 8; } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2718,16 +2653,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags |= 2), lastPlacedIndex) + ? ((newFiber.flags = 2), lastPlacedIndex) : newIndex ); - newFiber.flags |= 2; + newFiber.flags = 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags |= 2); + (newFiber.flags = 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2742,16 +2677,7 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - if (null !== current && current.elementType === elementType) + if (null !== current && current.elementType === element.type) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2865,7 +2791,15 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? updateElement(returnFiber, oldFiber, newChild, lanes) + ? newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ) + : updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2900,7 +2834,15 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - updateElement(returnFiber, existingChildren, newChild, lanes) + newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + existingChildren, + newChild.props.children, + lanes, + newChild.key + ) + : updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3096,48 +3038,53 @@ function ChildReconciler(shouldTrackSideEffects) { isUnkeyedTopLevelFragment && (newChild = newChild.props.children); var isObject = "object" === typeof newChild && null !== newChild; if (isObject) - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - a: { - isObject = newChild.key; - for ( - isUnkeyedTopLevelFragment = currentFirstChild; - null !== isUnkeyedTopLevelFragment; - - ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { - if (7 === isUnkeyedTopLevelFragment.tag) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: + a: { + isObject = newChild.key; + for ( + isUnkeyedTopLevelFragment = currentFirstChild; + null !== isUnkeyedTopLevelFragment; + + ) { + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3315,7 +3262,7 @@ function findFirstSuspended(row) { 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; + if (0 !== (node.flags & 64)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3467,11 +3414,10 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - pendingQueue = baseQueue.next; + baseQueue = baseQueue.next; current = current.baseState; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = pendingQueue; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3496,33 +3442,22 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (baseFirst = current)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== pendingQueue); + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (baseFirst = current) - : (newBaseQueueLast.next = newBaseQueueFirst); + ? (pendingQueue = current) + : (newBaseQueueLast.next = baseFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = baseFirst; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } - reducer = queue.interleaved; - if (null !== reducer) { - baseQueue = reducer; - do - (pendingQueue = baseQueue.lane), - (currentlyRenderingFiber$1.lanes |= pendingQueue), - (workInProgressRootSkippedLanes |= pendingQueue), - (baseQueue = baseQueue.next); - while (baseQueue !== reducer); - } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3562,7 +3497,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3592,13 +3527,25 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - objectIs(version, maybeNewVersion) || - ((maybeNewVersion = getSnapshot(source._source)), + if (!objectIs(version, maybeNewVersion)) { + maybeNewVersion = getSnapshot(source._source); objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), - markRootEntangled(root, root.mutableReadLanes)); + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); + maybeNewVersion = root.mutableReadLanes; + root.entangledLanes |= maybeNewVersion; + for ( + var entanglements = root.entanglements, lanes = maybeNewVersion; + 0 < lanes; + + ) { + var index$11 = 31 - clz32(lanes), + lane = 1 << index$11; + entanglements[index$11] |= maybeNewVersion; + lanes &= ~lane; + } + } }, [getSnapshot, source, subscribe] ); @@ -3625,8 +3572,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3652,8 +3597,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3702,7 +3645,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); + pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3710,10 +3653,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(132096, 4, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(1024, 4, create, deps); + return updateEffectImpl(516, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3798,55 +3741,33 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - alternate = fiber.alternate; + pending = queue.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + queue.pending = update; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), - (lane = queue.pending), - null === lane - ? (update.next = update) - : ((update.next = lane.next), (lane.next = update)), - (queue.pending = update); + didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; else { - if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { - var interleaved = queue.interleaved; - null === interleaved - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [queue]) - : interleavedQueues.push(queue)) - : ((update.next = interleaved.next), (interleaved.next = update)); - queue.interleaved = update; - } else - (interleaved = queue.pending), - null === interleaved - ? (update.next = update) - : ((update.next = interleaved.next), (interleaved.next = update)), - (queue.pending = update); if ( 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.lanes) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.eagerReducer = alternate; + eagerState = pending(currentState, action); + update.eagerReducer = pending; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - update = scheduleUpdateOnFiber(fiber, lane, eventTime); - 0 !== (lane & 8388096) && - null !== update && - ((fiber = queue.lanes), - (fiber &= update.pendingLanes), - (lane |= fiber), - (queue.lanes = lane), - markRootEntangled(update, lane)); + scheduleUpdateOnFiber(fiber, lane, eventTime); } } var ContextOnlyDispatcher = { @@ -3903,8 +3824,6 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4095,7 +4014,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4171,15 +4090,14 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) + ) + if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); - 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); - } return updateFunctionComponent( current, workInProgress, @@ -4196,40 +4114,31 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 2)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= renderLanes); - else { - if (0 === (renderLanes & 1073741824)) - return ( - (current = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { - baseLanes: current, - cachePool: null - }), - (workInProgress.updateQueue = null), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= current), - null + if (0 === (workInProgress.mode & 4)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes(workInProgress, renderLanes); + else if (0 !== (renderLanes & 1073741824)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes( + workInProgress, + null !== prevState ? prevState.baseLanes : renderLanes ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } + else + return ( + (current = + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { baseLanes: current }), + pushRenderLanes(workInProgress, current), + null + ); else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + pushRenderLanes(workInProgress, nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4239,7 +4148,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 256; + workInProgress.flags |= 128; } function updateFunctionComponent( current, @@ -4264,7 +4173,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4439,7 +4348,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 512)) + (workInProgress.flags |= 256)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4447,7 +4356,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4461,7 +4370,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (nextProps = !1)); } return finishClassComponent( @@ -4482,7 +4391,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 128); + var didCaptureError = 0 !== (workInProgress.flags & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4530,21 +4439,18 @@ function pushHostRootContext(workInProgress) { 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 = 0 !== (workInProgress.flags & 64)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -129)) + ? ((showFallback = !0), (workInProgress.flags &= -65)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4561,9 +4467,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4575,12 +4479,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432), current ); renderLanes = createFiberFromOffscreen( @@ -4606,11 +4508,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4637,11 +4536,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4664,10 +4560,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && null !== progressedPrimaryFragment + 0 === (mode & 2) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 4 && + workInProgress.mode & 8 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4702,14 +4598,13 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 2) && (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)); + ((current.nextEffect = null), + (current.flags = 8), + (workInProgress.firstEffect = workInProgress.lastEffect = current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4719,27 +4614,33 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child; + current = currentPrimaryChildFragment.sibling; + var primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 4 && + workInProgress.mode & 8 && ((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 & 131072)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) + (primaryChildren.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration), + (primaryChildren.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration)), + (currentPrimaryChildFragment = primaryChildren.lastEffect), + null !== currentPrimaryChildFragment + ? ((workInProgress.firstEffect = primaryChildren.firstEffect), + (workInProgress.lastEffect = currentPrimaryChildFragment), + (currentPrimaryChildFragment.nextEffect = null)) + : (workInProgress.firstEffect = workInProgress.lastEffect = null)) + : (primaryChildren = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )); + null !== current + ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4764,7 +4665,8 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode + tailMode, + lastEffectBeforeRendering ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4774,14 +4676,16 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode)); + (renderState.tailMode = tailMode), + (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4790,9 +4694,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); else { - if (null !== current && 0 !== (current.flags & 128)) + if (null !== current && 0 !== (current.flags & 64)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4815,7 +4719,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4836,7 +4740,8 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "backwards": @@ -4858,11 +4763,19 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + initSuspenseListRenderState( + workInProgress, + !1, + null, + null, + void 0, + workInProgress.lastEffect + ); break; default: workInProgress.memoizedState = null; @@ -4873,33 +4786,25 @@ 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; + if (0 !== (renderLanes & workInProgress.childLanes)) { + 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; } - return !0; + return null; } var appendAllChildren, updateHostContainer, @@ -5016,24 +4921,21 @@ function appendAllChildrenToContainer( node = node.sibling; } } -updateHostContainer = function(current, workInProgress) { +updateHostContainer = function(workInProgress) { var portalOrRoot = workInProgress.stateNode; - if (!hadNoMutationsEffects(current, workInProgress)) { - current = portalOrRoot.containerInfo; - var newChildSet = createChildNodeSet(current); + if (null !== workInProgress.firstEffect) { + var container = portalOrRoot.containerInfo, + newChildSet = createChildNodeSet(container); appendAllChildrenToContainer(newChildSet, workInProgress, !1, !1); portalOrRoot.pendingChildren = newChildSet; workInProgress.flags |= 4; - completeRoot(current, newChildSet); + completeRoot(container, newChildSet); } }; updateHostComponent$1 = function(current, workInProgress, type, newProps) { type = current.stateNode; var oldProps = current.memoizedProps; - if ( - (current = hadNoMutationsEffects(current, workInProgress)) && - oldProps === newProps - ) + if ((current = null === workInProgress.firstEffect) && oldProps === newProps) workInProgress.stateNode = type; else { var recyclableInstance = workInProgress.stateNode; @@ -5051,15 +4953,15 @@ updateHostComponent$1 = function(current, workInProgress, type, newProps) { current && null === updatePayload ? (workInProgress.stateNode = type) : ((newProps = updatePayload), - (oldProps = type.node), + (recyclableInstance = type.node), (type = { node: current ? null !== newProps - ? cloneNodeWithNewProps(oldProps, newProps) - : cloneNode(oldProps) + ? cloneNodeWithNewProps(recyclableInstance, newProps) + : cloneNode(recyclableInstance) : null !== newProps - ? cloneNodeWithNewChildrenAndProps(oldProps, newProps) - : cloneNodeWithNewChildren(oldProps), + ? cloneNodeWithNewChildrenAndProps(recyclableInstance, newProps) + : cloneNodeWithNewChildren(recyclableInstance), canonical: type.canonical }), (workInProgress.stateNode = type), @@ -5095,76 +4997,16 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$63 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + for (var lastTailNode$65 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$63 + null === lastTailNode$65 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$63.sibling = null); + : (lastTailNode$65.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 & 4)) { - for ( - var treeBaseDuration$65 = completedWork.selfBaseDuration, - child$66 = completedWork.child; - null !== child$66; - - ) - (newChildLanes |= child$66.lanes | child$66.childLanes), - (subtreeFlags |= child$66.subtreeFlags & 131072), - (subtreeFlags |= child$66.flags & 131072), - (treeBaseDuration$65 += child$66.treeBaseDuration), - (child$66 = child$66.sibling); - completedWork.treeBaseDuration = treeBaseDuration$65; - } else - for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; - - ) - (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 131072), - (subtreeFlags |= treeBaseDuration$65.flags & 131072), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); - else if (0 !== (completedWork.mode & 4)) { - treeBaseDuration$65 = completedWork.actualDuration; - child$66 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$65 += child.actualDuration), - (child$66 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$65; - completedWork.treeBaseDuration = child$66; - } else - for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; - - ) - (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags), - (subtreeFlags |= treeBaseDuration$65.flags), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -5178,81 +5020,76 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return bubbleProperties(workInProgress), null; + return null; case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 3: return ( - (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), + (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), + (workInProgress.flags |= 256), + updateHostContainer(workInProgress), null ); case 5: popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderLanes = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderLanes, newProps, - renderLanes + rootContainerInstance ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + current.ref !== workInProgress.ref && (workInProgress.flags |= 128); 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); + renderLanes = getViewConfigForType(renderLanes); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderLanes.validAttributes ); - renderLanes = createNode( + rootContainerInstance = createNode( current, - type.uiViewClassName, - renderLanes, + renderLanes.uiViewClassName, + rootContainerInstance, updatePayload, workInProgress ); current = new ReactFabricHostComponent( current, - type, + renderLanes, newProps, workInProgress ); - current = { node: renderLanes, canonical: current }; + current = { node: rootContainerInstance, canonical: current }; appendAllChildren(current, workInProgress, !1, !1); workInProgress.stateNode = current; - null !== workInProgress.ref && (workInProgress.flags |= 256); + null !== workInProgress.ref && (workInProgress.flags |= 128); } - bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5268,30 +5105,30 @@ function completeWork(current, workInProgress, renderLanes) { "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); + rootContainerInstance = requiredContext(contextStackCursor$1.current); workInProgress.stateNode = createTextInstance( newProps, current, - renderLanes, + rootContainerInstance, workInProgress ); } - bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) + if (0 !== (workInProgress.flags & 64)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 4) && + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) + rootContainerInstance = !1; + null !== current && + (rootContainerInstance = null !== current.memoizedState); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5306,100 +5143,89 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || + (0 === (workInProgressRootSkippedLanes & 134217727) && + 0 === (workInProgressRootUpdatedLanes & 134217727)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } newProps && (workInProgress.flags |= 4); - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 4) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); return null; case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); + return popProvider(workInProgress), null; case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 19: pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.flags & 64); + updatePayload = newProps.rendering; if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) + (null !== current && 0 !== (current.flags & 64)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); + workInProgress.flags |= 64; + cutOffTailIfNeeded(newProps, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), + (rootContainerInstance = newProps), (updatePayload = current), - (renderLanes.flags &= 131074), - (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 = type.subtreeFlags), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = + (rootContainerInstance.flags &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderLanes = rootContainerInstance.alternate), + null === renderLanes + ? ((rootContainerInstance.childLanes = 0), + (rootContainerInstance.lanes = updatePayload), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.stateNode = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childLanes = + renderLanes.childLanes), + (rootContainerInstance.lanes = renderLanes.lanes), + (rootContainerInstance.child = renderLanes.child), + (rootContainerInstance.memoizedProps = + renderLanes.memoizedProps), + (rootContainerInstance.memoizedState = + renderLanes.memoizedState), + (rootContainerInstance.updateQueue = + renderLanes.updateQueue), + (rootContainerInstance.type = renderLanes.type), + (updatePayload = renderLanes.dependencies), + (rootContainerInstance.dependencies = null === updatePayload ? null : { lanes: updatePayload.lanes, firstContext: updatePayload.firstContext }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), + (rootContainerInstance.selfBaseDuration = + renderLanes.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderLanes.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5409,76 +5235,80 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== type.tail && + null !== newProps.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608)); + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432)); } else { - if (!newProps) + if (!rootContainerInstance) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 128), - (newProps = !0), + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && !updatePayload.alternate) ) - return bubbleProperties(workInProgress), null; + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - 2 * now() - type.renderingStartTime > + 2 * now() - newProps.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608)); - type.isBackwards + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432)); + newProps.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), + : ((current = newProps.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + (newProps.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; + return null !== newProps.tail + ? ((current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (workInProgress = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 + ), + current) + : null; case 22: case 23: return ( popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== renderLanes && + (null !== current.memoizedState) !== + (null !== workInProgress.memoizedState) && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), - (renderLanes && - 0 === (subtreeRenderLanes & 1073741824) && - 0 !== (workInProgress.mode & 2)) || - bubbleProperties(workInProgress), null ); } @@ -5493,9 +5323,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), - 0 !== (workInProgress.mode & 4) && + return flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5505,11 +5335,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 128)) + if (0 !== (flags & 64)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -16385) | 128; + workInProgress.flags = (flags & -8193) | 64; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5517,9 +5347,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), - 0 !== (workInProgress.mode & 4) && + flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress) : null @@ -5529,12 +5359,10 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type._context), null; + return popProvider(workInProgress), null; case 22: case 23: return popRenderLanes(), null; - case 24: - return null; default: return null; } @@ -5613,161 +5441,164 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null; -function safelyDetachRef(current, nearestMountedAncestor) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; +function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, nearestMountedAncestor, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -var focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = null; - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) - doesFiberContain(firstChild[i], focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - firstChild = root.child; - if (0 !== (root.subtreeFlags & 516) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var current = root.alternate, - flags = root.flags; - if ( - !shouldFireAfterActiveInstanceBlur && - null !== focusedInstanceHandle - ) { - var JSCompiler_temp; - if ((JSCompiler_temp = 13 === root.tag)) - a: { - if (null !== current) { - var oldState = current.memoizedState; - if (null === oldState || null !== oldState.dehydrated) { - var newState = root.memoizedState; - JSCompiler_temp = - null !== newState && null === newState.dehydrated; - break a; - } - } - JSCompiler_temp = !1; - } - JSCompiler_temp && - doesFiberContain(root, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - } - if (0 !== (flags & 512)) - switch (root.tag) { - case 0: - case 11: - case 15: - break; - case 1: - if (null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState, - instance = root.stateNode, - snapshot = instance.getSnapshotBeforeUpdate( - root.elementType === root.type - ? prevProps - : resolveDefaultProps(root.type, prevProps), - prevState - ); - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - break; - case 3: - break; - case 5: - case 6: - case 4: - case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + return; + case 1: + if (finishedWork.flags & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } + return; + case 3: + return; + case 5: + case 6: + case 4: + case 17: + return; } - current = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - focusedInstanceHandle = null; - return current; + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor$jscomp$0 -) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; - if (void 0 !== destroy) { - var current = finishedWork, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); +function commitLifeCycles(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + if (3 === (finishedRoot.tag & 3)) { + var create$82 = finishedRoot.create; + finishedRoot.destroy = create$82(); } - } + finishedRoot = finishedRoot.next; + } while (finishedRoot !== current); } - effect = effect.next; - } while (effect !== updateQueue); - } -} -function commitHookEffectListMount(tag, finishedWork) { - finishedWork = finishedWork.updateQueue; - finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; - if (null !== finishedWork) { - var effect = (finishedWork = finishedWork.next); - do { - if ((effect.tag & tag) === tag) { - var create$84 = effect.create; - effect.destroy = create$84(); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + var _effect = finishedRoot; + create$82 = _effect.next; + _effect = _effect.tag; + 0 !== (_effect & 4) && + 0 !== (_effect & 1) && + (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), + enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); + finishedRoot = create$82; + } while (finishedRoot !== current); + } + return; + case 1: + finishedRoot = finishedWork.stateNode; + finishedWork.flags & 4 && + (null === current + ? finishedRoot.componentDidMount() + : ((create$82 = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current.memoizedProps + )), + finishedRoot.componentDidUpdate( + create$82, + current.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ))); + current = finishedWork.updateQueue; + null !== current && + commitUpdateQueue(finishedWork, current, finishedRoot); + return; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode.canonical; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue(finishedWork, current, finishedRoot); } - effect = effect.next; - } while (effect !== finishedWork); + return; + case 5: + null === current && finishedWork.flags & 4 && shim(); + return; + case 6: + return; + case 4: + return; + case 12: + create$82 = finishedWork.memoizedProps.onRender; + _effect = commitTime; + "function" === typeof create$82 && + create$82( + finishedWork.memoizedProps.id, + null === current ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + _effect, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + case 22: + case 23: + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function detachFiberAfterEffects(fiber) { +function detachFiberMutation(fiber) { fiber.alternate = null; fiber.child = null; - fiber.deletions = null; fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; + fiber.return = null; fiber.updateQueue = null; } function commitWork(current, finishedWork) { @@ -5776,7 +5607,19 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedWork = current = current.next; + do { + if (3 === (finishedWork.tag & 3)) { + var destroy = finishedWork.destroy; + finishedWork.destroy = void 0; + void 0 !== destroy && destroy(); + } + finishedWork = finishedWork.next; + } while (finishedWork !== current); + } return; case 12: return; @@ -5797,6 +5640,7 @@ function commitWork(current, finishedWork) { case 1: case 5: case 6: + case 20: break a; case 3: case 4: @@ -5817,291 +5661,20 @@ function attachSuspenseRetryListeners(finishedWork) { wakeables.forEach(function(wakeable) { var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); - }); - } -} -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - renderPriorityLevel = root.deletions; - if (null !== renderPriorityLevel) - for ( - firstChild = 0; - firstChild < renderPriorityLevel.length; - firstChild++ - ) { - var childToDelete = renderPriorityLevel[firstChild]; - try { - a: for (var node = childToDelete; ; ) { - var current = node; - if ( - injectedHook && - "function" === typeof injectedHook.onCommitFiberUnmount - ) - try { - injectedHook.onCommitFiberUnmount(rendererID, current); - } catch (err) {} - switch (current.tag) { - case 0: - case 11: - case 14: - case 15: - var updateQueue = current.updateQueue; - if (null !== updateQueue) { - var lastEffect = updateQueue.lastEffect; - if (null !== lastEffect) { - var firstEffect = lastEffect.next, - effect = firstEffect; - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; - if (void 0 !== destroy && 0 !== (tag & 2)) { - _effect = current; - var nearestMountedAncestor = root; - try { - destroy(); - } catch (error) { - captureCommitPhaseError( - _effect, - nearestMountedAncestor, - error - ); - } - } - effect = effect.next; - } while (effect !== firstEffect); - } - } - break; - case 1: - safelyDetachRef(current, root); - var instance = current.stateNode; - if ("function" === typeof instance.componentWillUnmount) - try { - (effect = current), - (_effect = instance), - (_effect.props = effect.memoizedProps), - (_effect.state = effect.memoizedState), - _effect.componentWillUnmount(); - } catch (unmountError) { - captureCommitPhaseError(current, root, unmountError); - } - break; - case 5: - safelyDetachRef(current, root); - break; - case 4: - createChildNodeSet(current.stateNode.containerInfo); - } - if (null !== node.child) - (node.child.return = node), (node = node.child); - else { - if (node === childToDelete) break; - for (; null === node.sibling; ) { - if (null === node.return || node.return === childToDelete) - break a; - node = node.return; - } - node.sibling.return = node.return; - node = node.sibling; - } - } - var alternate = childToDelete.alternate; - childToDelete.return = null; - null !== alternate && (alternate.return = null); - } catch (error) { - captureCommitPhaseError(childToDelete, root, error); - } - } - renderPriorityLevel = root.child; - if (0 !== (root.subtreeFlags & 6454) && null !== renderPriorityLevel) - (renderPriorityLevel.return = root), (nextEffect = renderPriorityLevel); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var flags = root.flags; - if (flags & 256) { - var current$jscomp$0 = root.alternate; - if (null !== current$jscomp$0) { - var currentRef = current$jscomp$0.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 2054) { - case 2: - root.flags &= -3; - break; - case 6: - root.flags &= -3; - commitWork(root.alternate, root); - break; - case 2048: - root.flags &= -2049; - break; - case 2052: - root.flags &= -2049; - commitWork(root.alternate, root); - break; - case 4: - commitWork(root.alternate, root); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - renderPriorityLevel = root.sibling; - if (null !== renderPriorityLevel) { - renderPriorityLevel.return = root.return; - nextEffect = renderPriorityLevel; - break; - } - nextEffect = root.return; - } + (!0 !== wakeable.__reactDoNotTraceInteractions && + (retry = tracing.unstable_wrap(retry)), + retryCache.add(wakeable), + wakeable.then(retry, retry)); + }); } } -function commitLayoutEffects(finishedWork, root) { - for (nextEffect = finishedWork; null !== nextEffect; ) { - var fiber = nextEffect, - firstChild = fiber.child; - if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) - (firstChild.return = fiber), (nextEffect = firstChild); - else - for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - if (0 !== (fiber$jscomp$0.flags & 324)) { - var current = fiber$jscomp$0.alternate; - try { - var finishedRoot = firstChild; - if (0 !== (fiber$jscomp$0.flags & 68)) - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(3, fiber$jscomp$0); - break; - case 1: - var instance = fiber$jscomp$0.stateNode; - if (fiber$jscomp$0.flags & 4) - if (null === current) instance.componentDidMount(); - else { - var prevProps = - fiber$jscomp$0.elementType === fiber$jscomp$0.type - ? current.memoizedProps - : resolveDefaultProps( - fiber$jscomp$0.type, - current.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = fiber$jscomp$0.updateQueue; - null !== updateQueue && - commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); - break; - case 3: - var updateQueue$85 = fiber$jscomp$0.updateQueue; - if (null !== updateQueue$85) { - finishedRoot = null; - if (null !== fiber$jscomp$0.child) - switch (fiber$jscomp$0.child.tag) { - case 5: - finishedRoot = - fiber$jscomp$0.child.stateNode.canonical; - break; - case 1: - finishedRoot = fiber$jscomp$0.child.stateNode; - } - commitUpdateQueue( - fiber$jscomp$0, - updateQueue$85, - finishedRoot - ); - } - break; - case 5: - null === current && fiber$jscomp$0.flags & 4 && shim(); - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = fiber$jscomp$0.memoizedProps.onRender, - commitTime$88 = commitTime; - current = null === current ? "mount" : "update"; - "function" === typeof onRender && - onRender( - fiber$jscomp$0.memoizedProps.id, - current, - fiber$jscomp$0.actualDuration, - fiber$jscomp$0.treeBaseDuration, - fiber$jscomp$0.actualStartTime, - commitTime$88, - finishedRoot.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 21: - case 22: - case 23: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - if (fiber$jscomp$0.flags & 256) { - finishedRoot = void 0; - var ref = fiber$jscomp$0.ref; - if (null !== ref) { - var instance$jscomp$0 = fiber$jscomp$0.stateNode; - switch (fiber$jscomp$0.tag) { - case 5: - finishedRoot = instance$jscomp$0.canonical; - break; - default: - finishedRoot = instance$jscomp$0; - } - "function" === typeof ref - ? ref(finishedRoot) - : (ref.current = finishedRoot); - } - } - } catch (error) { - captureCommitPhaseError( - fiber$jscomp$0, - fiber$jscomp$0.return, - error - ); - } - } - if (fiber$jscomp$0 === fiber) { - nextEffect = null; - break; - } - finishedRoot = fiber$jscomp$0.sibling; - if (null !== finishedRoot) { - finishedRoot.return = fiber$jscomp$0.return; - nextEffect = finishedRoot; - break; - } - nextEffect = fiber$jscomp$0.return; - } - } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + return null !== current && + ((current = current.memoizedState), + null === current || null !== current.dehydrated) + ? ((finishedWork = finishedWork.memoizedState), + null !== finishedWork && null === finishedWork.dehydrated) + : !1; } var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, @@ -6114,11 +5687,14 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, + workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, + mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6126,12 +5702,17 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, + pendingPassiveHookEffectsMount = [], + pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventTransitionLane = 0; + currentEventWipLanes = 0, + currentEventPendingLanes = 0, + focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6141,22 +5722,30 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 1)) return 1; - if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - if (0 !== ReactCurrentBatchConfig.transition) - return ( - 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), - (currentEventTransitionLane = fiber)), - currentEventTransitionLane - ); + if (0 === (fiber & 2)) return 1; + if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + 0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes); + if (0 !== ReactCurrentBatchConfig.transition) { + 0 !== currentEventPendingLanes && + (currentEventPendingLanes = + null !== mostRecentlyUpdatedRoot + ? mostRecentlyUpdatedRoot.pendingLanes + : 0); + fiber = currentEventWipLanes; + var lane = 4186112 & ~currentEventPendingLanes; + lane &= -lane; + 0 === lane && + ((fiber = 4186112 & ~fiber), + (lane = fiber & -fiber), + 0 === lane && (lane = 8192)); + return lane; + } fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12)) + ? (fiber = findUpdateLane(12, currentEventWipLanes)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber))); + (fiber = findUpdateLane(fiber, currentEventWipLanes))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6189,7 +5778,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - return fiber; + mostRecentlyUpdatedRoot = fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6237,42 +5826,45 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - 0 === suspendedLanes - ? (null !== existingCallbackNode && + if (0 === suspendedLanes) + null !== existingCallbackNode && + (existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)) - : root.callbackPriority !== currentTime && - (null != existingCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = null)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority( - currentTime - )), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))), - (root.callbackPriority = currentTime), - (root.callbackNode = existingCallbackNode)); -} -function performConcurrentWorkOnRoot(root, didTimeout) { + (root.callbackPriority = 0)); + else { + if (null !== existingCallbackNode) { + if (root.callbackPriority === currentTime) return; + existingCallbackNode !== fakeCallbackNode && + Scheduler_cancelCallback(existingCallbackNode); + } + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = fakeCallbackNode)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))); + root.callbackPriority = currentTime; + root.callbackNode = existingCallbackNode; + } +} +function performConcurrentWorkOnRoot(root) { currentEventTime = -1; - currentEventTransitionLane = 0; + currentEventPendingLanes = currentEventWipLanes = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6283,14 +5875,8 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - (root.expiredLanes |= lanes & root.pendingLanes), - ensureRootIsScheduled(root, now()), - null - ); var lanes$jscomp$0 = lanes; - didTimeout = executionContext; + var exitStatus = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -6312,19 +5898,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = didTimeout; + executionContext = exitStatus; null !== workInProgress - ? (didTimeout = 0) + ? (exitStatus = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); - if (0 !== didTimeout) { - 2 === didTimeout && + (exitStatus = workInProgressRootExitStatus)); + if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) + prepareFreshStack(root, 0); + else if (0 !== exitStatus) { + 2 === exitStatus && ((executionContext |= 64), root.hydrate && ((root.hydrate = !1), shim(root.containerInfo)), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); - if (1 === didTimeout) + 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (1 === exitStatus) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6332,7 +5920,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (didTimeout) { + switch (exitStatus) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6342,9 +5930,9 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 125829120) === lanes && - ((didTimeout = globalMostRecentFallbackTime + 500 - now()), - 10 < didTimeout) + (lanes & 62914560) === lanes && + ((exitStatus = globalMostRecentFallbackTime + 500 - now()), + 10 < exitStatus) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -6355,7 +5943,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - didTimeout + exitStatus ); break; } @@ -6363,12 +5951,12 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 8388096) === lanes) break; - didTimeout = root.eventTimes; + if ((lanes & 4186112) === lanes) break; + exitStatus = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { var index$4 = 31 - clz32(lanes); lanes$jscomp$0 = 1 << index$4; - index$4 = didTimeout[index$4]; + index$4 = exitStatus[index$4]; index$4 > prevDispatcher && (prevDispatcher = index$4); lanes &= ~lanes$jscomp$0; } @@ -6415,9 +6003,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$6 = 31 - clz32(suspendedLanes), - lane = 1 << index$6; - root[index$6] = -1; + var index$9 = 31 - clz32(suspendedLanes), + lane = 1 << index$9; + root[index$9] = -1; suspendedLanes &= ~lane; } } @@ -6425,12 +6013,17 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes = + if ( root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ? workInProgressRootRenderLanes - : getNextLanes(root, 0); - var exitStatus = renderRootSync(root, lanes); + ) { + var lanes = workInProgressRootRenderLanes; + var exitStatus = renderRootSync(root, lanes); + 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && + ((lanes = getNextLanes(root, lanes)), + (exitStatus = renderRootSync(root, lanes))); + } else + (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6449,6 +6042,11 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } +function pushRenderLanes(fiber, lanes) { + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= lanes; + workInProgressRootIncludedLanes |= lanes; +} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6488,7 +6086,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type._context); + popProvider(interruptedWork); break; case 22: case 23: @@ -6498,29 +6096,10 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - if (null !== interleavedQueues) { - for (root = 0; root < interleavedQueues.length; root++) - if ( - ((lanes = interleavedQueues[root]), - (timeoutHandle = lanes.interleaved), - null !== timeoutHandle) - ) { - lanes.interleaved = null; - interruptedWork = timeoutHandle.next; - var lastPendingUpdate = lanes.pending; - if (null !== lastPendingUpdate) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = interruptedWork; - timeoutHandle.next = firstPendingUpdate; - } - lanes.pending = timeoutHandle; - } - interleavedQueues = null; - } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6551,7 +6130,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 4 && + erroredWork.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6559,18 +6138,15 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 8192; + sourceFiber.flags |= 4096; + sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value, - tag = sourceFiber.tag; - if ( - 0 === (sourceFiber.mode & 1) && - (0 === tag || 11 === tag || 15 === tag) - ) { + var wakeable = value; + if (0 === (sourceFiber.mode & 2)) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6581,15 +6157,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$79 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { - var nextState = workInProgress$79.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$79.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6601,19 +6177,16 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$79.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$79.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); - if ( - 0 === (workInProgress$79.mode & 1) && - workInProgress$79 !== returnFiber - ) { - workInProgress$79.flags |= 128; - sourceFiber.flags |= 65536; - sourceFiber.flags &= -10053; + if (0 === (workInProgress$77.mode & 2)) { + workInProgress$77.flags |= 64; + sourceFiber.flags |= 32768; + sourceFiber.flags &= -5029; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6644,12 +6217,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$79.flags |= 16384; - workInProgress$79.lanes = thrownValue; + workInProgress$77.flags |= 8192; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6658,47 +6231,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$79 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$79.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$79.flags |= 16384; + workInProgress$77.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$80 = createRootErrorUpdate( - workInProgress$79, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$80); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$79.type, - instance = workInProgress$79.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$79.flags & 128) && + 0 === (workInProgress$77.flags & 64) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$79.flags |= 16384; + workInProgress$77.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$83 = createClassErrorUpdate( - workInProgress$79, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$83); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6757,7 +6330,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6774,8 +6347,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 8192)) { - if (0 === (completedWork.mode & 4)) + if (0 === (completedWork.flags & 4096)) { + if (0 === (completedWork.mode & 8)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -6788,14 +6361,65 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } + current = completedWork; + if ( + (23 !== current.tag && 22 !== current.tag) || + null === current.memoizedState || + 0 !== (subtreeRenderLanes & 1073741824) || + 0 === (current.mode & 4) + ) { + fiber = 0; + if (0 !== (current.mode & 8)) { + for ( + var actualDuration = current.actualDuration, + treeBaseDuration = current.selfBaseDuration, + shouldBubbleActualDurations = + null === current.alternate || + current.child !== current.alternate.child, + child = current.child; + null !== child; + + ) + (fiber |= child.lanes | child.childLanes), + shouldBubbleActualDurations && + (actualDuration += child.actualDuration), + (treeBaseDuration += child.treeBaseDuration), + (child = child.sibling); + 13 === current.tag && + null !== current.memoizedState && + ((shouldBubbleActualDurations = current.child), + null !== shouldBubbleActualDurations && + (treeBaseDuration -= + shouldBubbleActualDurations.treeBaseDuration)); + current.actualDuration = actualDuration; + current.treeBaseDuration = treeBaseDuration; + } else + for (actualDuration = current.child; null !== actualDuration; ) + (fiber |= actualDuration.lanes | actualDuration.childLanes), + (actualDuration = actualDuration.sibling); + current.childLanes = fiber; + } + null !== unitOfWork && + 0 === (unitOfWork.flags & 4096) && + (null === unitOfWork.firstEffect && + (unitOfWork.firstEffect = completedWork.firstEffect), + null !== completedWork.lastEffect && + (null !== unitOfWork.lastEffect && + (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), + (unitOfWork.lastEffect = completedWork.lastEffect)), + 1 < completedWork.flags && + (null !== unitOfWork.lastEffect + ? (unitOfWork.lastEffect.nextEffect = completedWork) + : (unitOfWork.firstEffect = completedWork), + (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 8191; + current.flags &= 4095; workInProgress = current; return; } - if (0 !== (completedWork.mode & 4)) { + if (0 !== (completedWork.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -6803,9 +6427,8 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.flags |= 8192), - (unitOfWork.subtreeFlags = 0), - (unitOfWork.deletions = null)); + ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), + (unitOfWork.flags |= 4096)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6836,65 +6459,271 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - markRootFinished(root, remainingLanes); + var remainingLanes = finishedWork.lanes | finishedWork.childLanes, + remainingLanes$jscomp$0 = remainingLanes, + noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; + root.pendingLanes = remainingLanes$jscomp$0; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes$jscomp$0; + root.mutableReadLanes &= remainingLanes$jscomp$0; + root.entangledLanes &= remainingLanes$jscomp$0; + remainingLanes$jscomp$0 = root.entanglements; + for ( + var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; + 0 < noLongerPendingLanes; + + ) { + var index$10 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$10; + remainingLanes$jscomp$0[index$10] = 0; + eventTimes[index$10] = -1; + expirationTimes[index$10] = -1; + noLongerPendingLanes &= ~lane; + } null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 8) && + 0 === (remainingLanes & 24) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 1040) && - 0 === (finishedWork.flags & 1040)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - remainingLanes = 0 !== (finishedWork.flags & 8054); - if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = executionContext; + 1 < finishedWork.flags + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (remainingLanes = finishedWork.firstEffect)) + : (remainingLanes = finishedWork) + : (remainingLanes = finishedWork.firstEffect); + if (null !== remainingLanes) { + remainingLanes$jscomp$0 = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root); - ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); + eventTimes = pushInteractions(root); + focusedInstanceHandle = ReactCurrentOwner$2.current = null; + shouldFireAfterActiveInstanceBlur = !1; + nextEffect = remainingLanes; + do + try { + commitBeforeMutationEffects(); + } catch (error) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + focusedInstanceHandle = null; commitTime = now$1(); - commitMutationEffects(root, renderPriorityLevel, finishedWork); + nextEffect = remainingLanes; + do + try { + for (; null !== nextEffect; ) { + var flags = nextEffect.flags; + if (flags & 128) { + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 1038) { + case 2: + nextEffect.flags &= -3; + break; + case 6: + nextEffect.flags &= -3; + commitWork(nextEffect.alternate, nextEffect); + break; + case 1024: + nextEffect.flags &= -1025; + break; + case 1028: + nextEffect.flags &= -1025; + commitWork(nextEffect.alternate, nextEffect); + break; + case 4: + commitWork(nextEffect.alternate, nextEffect); + break; + case 8: + expirationTimes = nextEffect; + a: for (index$10 = noLongerPendingLanes = expirationTimes; ; ) { + lane = index$10; + if ( + injectedHook && + "function" === typeof injectedHook.onCommitFiberUnmount + ) + try { + injectedHook.onCommitFiberUnmount(rendererID, lane); + } catch (err) {} + switch (lane.tag) { + case 0: + case 11: + case 14: + case 15: + var updateQueue = lane.updateQueue; + if (null !== updateQueue) { + var lastEffect = updateQueue.lastEffect; + if (null !== lastEffect) { + var firstEffect = lastEffect.next, + effect = firstEffect; + do { + var _effect2 = effect, + destroy = _effect2.destroy, + tag = _effect2.tag; + if (void 0 !== destroy) + if (0 !== (tag & 4)) + enqueuePendingPassiveHookEffectUnmount( + lane, + effect + ); + else { + _effect2 = lane; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect2, error); + } + } + effect = effect.next; + } while (effect !== firstEffect); + } + } + break; + case 1: + safelyDetachRef(lane); + var instance = lane.stateNode; + if ("function" === typeof instance.componentWillUnmount) + try { + (effect = lane), + (_effect2 = instance), + (_effect2.props = effect.memoizedProps), + (_effect2.state = effect.memoizedState), + _effect2.componentWillUnmount(); + } catch (unmountError) { + captureCommitPhaseError(lane, unmountError); + } + break; + case 5: + safelyDetachRef(lane); + break; + case 4: + createChildNodeSet(lane.stateNode.containerInfo); + } + if (null !== index$10.child) + (index$10.child.return = index$10), + (index$10 = index$10.child); + else { + if (index$10 === noLongerPendingLanes) break; + for (; null === index$10.sibling; ) { + if ( + null === index$10.return || + index$10.return === noLongerPendingLanes + ) + break a; + index$10 = index$10.return; + } + index$10.sibling.return = index$10.return; + index$10 = index$10.sibling; + } + } + var alternate = expirationTimes.alternate; + detachFiberMutation(expirationTimes); + null !== alternate && detachFiberMutation(alternate); + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$90) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$90); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + nextEffect = remainingLanes; + do + try { + for (flags = root; null !== nextEffect; ) { + var flags$jscomp$0 = nextEffect.flags; + flags$jscomp$0 & 36 && + commitLifeCycles(flags, nextEffect.alternate, nextEffect); + if (flags$jscomp$0 & 128) { + current = void 0; + var ref = nextEffect.ref; + if (null !== ref) { + var instance$jscomp$0 = nextEffect.stateNode; + switch (nextEffect.tag) { + case 5: + current = instance$jscomp$0.canonical; + break; + default: + current = instance$jscomp$0; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$91) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$91); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + nextEffect = null; requestPaint(); - tracing.__interactionsRef.current = prevInteractions; - executionContext = remainingLanes; + tracing.__interactionsRef.current = eventTimes; + executionContext = remainingLanes$jscomp$0; } else (root.current = finishedWork), (commitTime = now$1()); - if ((prevInteractions = rootDoesHavePassiveEffects)) + if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); + else + for (nextEffect = remainingLanes; null !== nextEffect; ) + (ref = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + nextEffect.flags & 8 && + ((instance$jscomp$0 = nextEffect), + (instance$jscomp$0.sibling = null), + (instance$jscomp$0.stateNode = null)), + (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - for (var i = 0; i < expirationTimes.length; i++) + if (null !== spawnedWorkDuringRender) + for ( + ref = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + instance$jscomp$0 = 0; + instance$jscomp$0 < ref.length; + instance$jscomp$0++ + ) scheduleInteractions( root, - expirationTimes[i], + ref[instance$jscomp$0], root.memoizedInteractions ); - } schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - prevInteractions || finishPendingInteractions(root, lanes); - 0 !== (remainingLanes & 1) + flags$jscomp$0 || finishPendingInteractions(root, lanes); + 1 === remainingLanes ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + finishedWork = finishedWork.stateNode; + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + finishedWork, + renderPriorityLevel, + 64 === (finishedWork.current.flags & 64) + ); + } catch (err) {} ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6905,6 +6734,30 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } +function commitBeforeMutationEffects() { + for (; null !== nextEffect; ) { + var current = nextEffect.alternate; + shouldFireAfterActiveInstanceBlur || + null === focusedInstanceHandle || + (0 !== (nextEffect.flags & 8) + ? doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0) + : 13 === nextEffect.tag && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0)); + var flags = nextEffect.flags; + 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); + 0 === (flags & 512) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + nextEffect = nextEffect.nextEffect; + } +} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6916,6 +6769,24 @@ function flushPassiveEffects() { } return !1; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -6926,104 +6797,41 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root); - for (nextEffect = root.current; null !== nextEffect; ) { - var fiber = nextEffect, - child = fiber.child; - if (0 !== (nextEffect.flags & 16)) { - var deletions = fiber.deletions; - if (null !== deletions) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - for (nextEffect = fiberToDelete; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); - } - var child$jscomp$0 = fiber$jscomp$0.child; - if (null !== child$jscomp$0) - (child$jscomp$0.return = fiber$jscomp$0), - (nextEffect = child$jscomp$0); - else - for (; null !== nextEffect; ) { - fiber$jscomp$0 = nextEffect; - if (fiber$jscomp$0 === fiberToDelete) { - nextEffect = null; - break; - } - child$jscomp$0 = fiber$jscomp$0.sibling; - if (null !== child$jscomp$0) { - child$jscomp$0.return = fiber$jscomp$0.return; - nextEffect = child$jscomp$0; - break; - } - nextEffect = fiber$jscomp$0.return; - } - } - fiber$jscomp$0 = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); - null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); - } - nextEffect = fiber; + var prevInteractions = pushInteractions(root), + unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + for (var i = 0; i < unmountEffects.length; i += 2) { + var effect$96 = unmountEffects[i], + fiber = unmountEffects[i + 1], + destroy = effect$96.destroy; + effect$96.destroy = void 0; + if ("function" === typeof destroy) + try { + destroy(); + } catch (error) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error); } + } + unmountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + for (i = 0; i < unmountEffects.length; i += 2) { + effect$96 = unmountEffects[i]; + fiber = unmountEffects[i + 1]; + try { + var create$100 = effect$96.create; + effect$96.destroy = create$100(); + } catch (error$101) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error$101); } - if (0 !== (fiber.subtreeFlags & 1040) && null !== child) - (child.return = fiber), (nextEffect = child); - else - a: for (; null !== nextEffect; ) { - fiber = nextEffect; - if (0 !== (fiber.flags & 1024)) - switch (fiber.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(5, fiber, fiber.return); - } - child = fiber.sibling; - if (null !== child) { - child.return = fiber.return; - nextEffect = child; - break a; - } - nextEffect = fiber.return; - } } - for (nextEffect = fiber = root.current; null !== nextEffect; ) - if ( - ((child = nextEffect), - (deletions = child.child), - 0 !== (child.subtreeFlags & 1040) && null !== deletions) - ) - (deletions.return = child), (nextEffect = deletions); - else - a: for (child = fiber; null !== nextEffect; ) { - deletions = nextEffect; - if (0 !== (deletions.flags & 1024)) - try { - switch (deletions.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(5, deletions); - } - } catch (error) { - captureCommitPhaseError(deletions, deletions.return, error); - } - if (deletions === child) { - nextEffect = null; - break a; - } - i = deletions.sibling; - if (null !== i) { - i.return = deletions.return; - nextEffect = i; - break a; - } - nextEffect = deletions.return; - } + for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) + (create$100 = unmountEffects.nextEffect), + (unmountEffects.nextEffect = null), + unmountEffects.flags & 8 && + ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), + (unmountEffects = create$100); tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -7041,51 +6849,43 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { +function captureCommitPhaseError(sourceFiber, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for ( - nearestMountedAncestor = sourceFiber.return; - null !== nearestMountedAncestor; - - ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error - ); + for (var fiber = sourceFiber.return; null !== fiber; ) { + if (3 === fiber.tag) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); break; - } else if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; + } else if (1 === fiber.tag) { + var instance = fiber.stateNode; if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || + "function" === typeof fiber.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - sourceFiber = createClassErrorUpdate( - nearestMountedAncestor, - sourceFiber, - 1 - ); - enqueueUpdate(nearestMountedAncestor, sourceFiber); - sourceFiber = requestEventTime(); - nearestMountedAncestor = markUpdateLaneFromFiberToRoot( - nearestMountedAncestor, - 1 - ); - null !== nearestMountedAncestor && - (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), - schedulePendingInteractions(nearestMountedAncestor, 1)); + var update = createClassErrorUpdate(fiber, sourceFiber, 1); + enqueueUpdate(fiber, update); + update = requestEventTime(); + fiber = markUpdateLaneFromFiberToRoot(fiber, 1); + if (null !== fiber) + markRootUpdated(fiber, 1, update), + ensureRootIsScheduled(fiber, update), + schedulePendingInteractions(fiber, 1); + else if ( + "function" === typeof instance.componentDidCatch && + (null === legacyErrorBoundariesThatAlreadyFailed || + !legacyErrorBoundariesThatAlreadyFailed.has(instance)) + ) + try { + instance.componentDidCatch(error, sourceFiber); + } catch (errorToIgnore) {} break; } } - nearestMountedAncestor = nearestMountedAncestor.return; + fiber = fiber.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7097,7 +6897,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 125829120) === + (workInProgressRootRenderLanes & 62914560) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -7111,13 +6911,14 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 1) + 0 === (wakeable & 2) ? (wakeable = 1) - : 0 === (wakeable & 2) + : 0 === (wakeable & 4) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : ((wakeable = nextRetryLane), - (nextRetryLane <<= 1), - 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); + : (0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes), + (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), + 0 === wakeable && (wakeable = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -7134,90 +6935,85 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; + else if (0 !== (renderLanes & updateLanes)) + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; 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( + 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.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue2); + context._currentValue2 = updateLanes; + 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 ); - 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) + workInProgress = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); - } - return 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 & 64)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 64; + } + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); } - didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7229,22 +7025,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateLanes, 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; @@ -7254,8 +7050,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7266,9 +7062,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7280,28 +7076,28 @@ beginWork$1 = function(current, workInProgress, 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; + context = 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); + hasContext = context._init; + context = hasContext(context._payload); + workInProgress.type = context; + hasContext = workInProgress.tag = resolveLazyComponentTag(context); + current = resolveDefaultProps(context, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7310,7 +7106,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7319,7 +7115,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7328,8 +7124,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), + context, + resolveDefaultProps(context.type, current), updateLanes, renderLanes ); @@ -7337,7 +7133,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + context + ". Lazy element type must resolve to a class or function." ); } @@ -7345,32 +7141,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateFunctionComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateClassComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7381,18 +7177,19 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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; + updateLanes = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + updateLanes = workInProgress.memoizedState.element; + updateLanes === context ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7432,16 +7229,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateForwardRef( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7482,21 +7279,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = nextValue.value; - push(valueCursor, updateLanes._currentValue2); - updateLanes._currentValue2 = hasContext; - if (null !== getDerivedStateFromProps) { - var oldValue = getDerivedStateFromProps.value; - hasContext = objectIs(oldValue, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits(oldValue, hasContext) - : 1073741823) | 0; - if (0 === hasContext) { + hasContext = context.value; + var context$jscomp$0 = workInProgress.type._context; + push(valueCursor, context$jscomp$0._currentValue2); + context$jscomp$0._currentValue2 = hasContext; + if (null !== getDerivedStateFromProps) + if ( + ((context$jscomp$0 = getDerivedStateFromProps.value), + (hasContext = objectIs(context$jscomp$0, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits( + context$jscomp$0, + hasContext + ) + : 1073741823) | 0), + 0 === hasContext) + ) { if ( - getDerivedStateFromProps.children === nextValue.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7508,14 +7311,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7525,24 +7329,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - if (1 === oldValue.tag) { - dependency = createUpdate(-1, renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = oldValue.updateQueue; - if (null !== updateQueue) { - updateQueue = updateQueue.shared; - var pending = updateQueue.pending; - null === pending - ? (dependency.next = dependency) - : ((dependency.next = pending.next), - (pending.next = dependency)); - updateQueue.pending = dependency; - } - } - oldValue.lanes |= renderLanes; - dependency = oldValue.alternate; + 1 === context$jscomp$0.tag && + ((dependency = createUpdate( + -1, + renderLanes & -renderLanes + )), + (dependency.tag = 2), + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.lanes |= renderLanes; + dependency = context$jscomp$0.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath(oldValue.return, renderLanes); + scheduleWorkOnParentPath( + context$jscomp$0.return, + renderLanes + ); list.lanes |= renderLanes; break; } @@ -7550,16 +7350,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7567,21 +7367,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7589,28 +7388,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(context)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - nextValue, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( current, workInProgress, - nextValue, + context, hasContext, updateLanes, renderLanes @@ -7628,11 +7427,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7642,8 +7441,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, updateLanes, context), + mountClassInstance(workInProgress, updateLanes, context, renderLanes), finishClassComponent( null, workInProgress, @@ -7744,9 +7543,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$95) { + } catch (error$102) { scheduleCallback(99, function() { - throw error$95; + throw error$102; }); } })); @@ -7762,8 +7561,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.subtreeFlags = this.flags = 0; - this.deletions = null; + this.flags = 0; + this.lastEffect = this.firstEffect = this.nextEffect = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -7804,11 +7603,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), + (workInProgress.nextEffect = null), + (workInProgress.firstEffect = null), + (workInProgress.lastEffect = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7845,18 +7644,15 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 8; + mode |= 16; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 16); + mode |= 1; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -8047,8 +7843,7 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - element = scheduleUpdateOnFiber(current, lane, eventTime); - null !== element && entangleTransitions(element, current, lane); + scheduleUpdateOnFiber(current, lane, eventTime); return lane; } function emptyFindFiberByHostInstance() { @@ -8080,10 +7875,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_941 = { + devToolsConfig$jscomp$inline_887 = { findFiberByHostInstance: getInstanceFromInstance, bundleType: 0, - version: "17.0.2", + version: "17.0.1-454c2211c", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8098,11 +7893,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1218 = { - bundleType: devToolsConfig$jscomp$inline_941.bundleType, - version: devToolsConfig$jscomp$inline_941.version, - rendererPackageName: devToolsConfig$jscomp$inline_941.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_941.rendererConfig, +var internals$jscomp$inline_1087 = { + bundleType: devToolsConfig$jscomp$inline_887.bundleType, + version: devToolsConfig$jscomp$inline_887.version, + rendererPackageName: devToolsConfig$jscomp$inline_887.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_887.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8117,7 +7912,7 @@ var internals$jscomp$inline_1218 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_941.findFiberByHostInstance || + devToolsConfig$jscomp$inline_887.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -8126,16 +7921,16 @@ var internals$jscomp$inline_1218 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1219 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1088 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1219.isDisabled && - hook$jscomp$inline_1219.supportsFiber + !hook$jscomp$inline_1088.isDisabled && + hook$jscomp$inline_1088.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1219.inject( - internals$jscomp$inline_1218 + (rendererID = hook$jscomp$inline_1088.inject( + internals$jscomp$inline_1087 )), - (injectedHook = hook$jscomp$inline_1219); + (injectedHook = hook$jscomp$inline_1088); } catch (err) {} } exports.createPortal = function(children, containerTag) { @@ -8178,7 +7973,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 4); + isDevToolsPresent && (JSCompiler_inline_result |= 8); JSCompiler_inline_result = createFiber( 3, null, @@ -8187,7 +7982,6 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 96a631c87dd349..6b9ea503d3866e 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -1237,10 +1237,10 @@ var LazyComponent = 16; var IncompleteClassComponent = 17; var DehydratedFragment = 18; var SuspenseListComponent = 19; +var FundamentalComponent = 20; var ScopeComponent = 21; var OffscreenComponent = 22; var LegacyHiddenComponent = 23; -var CacheComponent = 24; /** * Instance of element that should respond to touch/move types of interactions, @@ -2864,12 +2864,12 @@ var REACT_SUSPENSE_TYPE = 0xead1; var REACT_SUSPENSE_LIST_TYPE = 0xead8; var REACT_MEMO_TYPE = 0xead3; var REACT_LAZY_TYPE = 0xead4; +var REACT_FUNDAMENTAL_TYPE = 0xead5; var REACT_SCOPE_TYPE = 0xead7; var REACT_OPAQUE_ID_TYPE = 0xeae0; var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1; var REACT_OFFSCREEN_TYPE = 0xeae2; var REACT_LEGACY_HIDDEN_TYPE = 0xeae3; -var REACT_CACHE_TYPE = 0xeae4; if (typeof Symbol === "function" && Symbol.for) { var symbolFor = Symbol.for; @@ -2885,12 +2885,12 @@ if (typeof Symbol === "function" && Symbol.for) { REACT_SUSPENSE_LIST_TYPE = symbolFor("react.suspense_list"); REACT_MEMO_TYPE = symbolFor("react.memo"); REACT_LAZY_TYPE = symbolFor("react.lazy"); + REACT_FUNDAMENTAL_TYPE = symbolFor("react.fundamental"); REACT_SCOPE_TYPE = symbolFor("react.scope"); REACT_OPAQUE_ID_TYPE = symbolFor("react.opaque.id"); REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator; @@ -2964,9 +2964,6 @@ function getComponentName(type) { case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - - case REACT_CACHE_TYPE: - return "Cache"; } if (typeof type === "object") { @@ -3004,10 +3001,9 @@ function getComponentName(type) { // The rest of the flags are static for better dead code elimination. var enableProfilerTimer = true; -var enableLazyElements = false; +var enableFundamentalAPI = false; var warnAboutStringRefs = false; var enableNewReconciler = false; -var deferRenderPhaseUpdateToNextBatch = true; // Don't change these two values. They're used by React Dev Tools. var NoFlags = @@ -3025,84 +3021,53 @@ var Update = 4; var PlacementAndUpdate = /* */ - Placement | Update; -var ChildDeletion = - /* */ - 16; + 6; +var Deletion = + /* */ + 8; var ContentReset = /* */ - 32; + 16; var Callback = /* */ - 64; + 32; var DidCapture = /* */ - 128; + 64; var Ref = /* */ - 256; + 128; var Snapshot = /* */ - 512; + 256; var Passive = /* */ - 1024; + 512; var Hydrating = /* */ - 2048; + 1024; var HydratingAndUpdate = /* */ - Hydrating | Update; -var Visibility = - /* */ - 4096; + 1028; var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot; // Union of all commit flags (flags with the lifetime of a particular commit) var HostEffectMask = /* */ - 8191; // These are not really side effects, but we still reuse this field. + 4095; // These are not really side effects, but we still reuse this field. var Incomplete = /* */ - 8192; + 4096; var ShouldCapture = /* */ - 16384; // TODO (effects) Remove this bit once the new reconciler is synced to the old. + 8192; // TODO (effects) Remove this bit once the new reconciler is synced to the old. var PassiveUnmountPendingDev = /* */ - 32768; + 16384; var ForceUpdateForLegacySuspense = /* */ - 65536; // Static tags describe aspects of a fiber that are not specific to a render, -// e.g. a fiber uses a passive effect (even if there are no updates on this particular render). -// This enables us to defer more work in the unmount case, -// since we can defer traversing the tree during layout to look for Passive effects, -// and instead rely on the static flag as a signal that there may be cleanup work. - -var PassiveStatic = - /* */ - 131072; // These flags allow us to traverse to fibers that have effects on mount -// don't contain effects, by checking subtreeFlags. - -var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visiblity - // flag logic (see #20043) - Update | Snapshot | 0; -var MutationMask = - Placement | - Update | - ChildDeletion | - ContentReset | - Ref | - Hydrating | - Visibility; -var LayoutMask = Update | Callback | Ref; // TODO: Split into PassiveMountMask and PassiveUnmountMask - -var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones. -// This allows certain concepts to persist without recalculting them, -// e.g. whether a subtree contains passive effects or portals. - -var StaticMask = PassiveStatic; + 32768; // Static tags describe aspects of a fiber that are not specific to a render, var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; function getNearestMountedFiber(fiber) { @@ -3342,28 +3307,38 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { var currentParent = findCurrentFiberUsingSlowPath(parent); - return currentParent !== null - ? findCurrentHostFiberImpl(currentParent) - : null; -} -function findCurrentHostFiberImpl(node) { - // Next we'll drill down this component to find the first HostComponent/Text. - if (node.tag === HostComponent || node.tag === HostText) { - return node; - } + if (!currentParent) { + return null; + } // Next we'll drill down this component to find the first HostComponent/Text. - var child = node.child; + var node = currentParent; - while (child !== null) { - var match = findCurrentHostFiberImpl(child); + while (true) { + if (node.tag === HostComponent || node.tag === HostText) { + return node; + } else if (node.child) { + node.child.return = node; + node = node.child; + continue; + } - if (match !== null) { - return match; + if (node === currentParent) { + return null; } - child = child.sibling; - } + while (!node.sibling) { + if (!node.return || node.return === currentParent) { + return null; + } + + node = node.return; + } + + node.sibling.return = node.return; + node = node.sibling; + } // Flow needs the return null here, but ESLint complains about it. + // eslint-disable-next-line no-unreachable return null; } @@ -3984,2195 +3959,2146 @@ var ReactNativeFiberHostComponent = /*#__PURE__*/ (function() { return ReactNativeFiberHostComponent; })(); // eslint-disable-next-line no-unused-expressions -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +// can re-export everything from this module. -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { +function shim() { + { throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); } -} - -// Except for NoPriority, these correspond to Scheduler priorities. We use -// ascending numbers so we can compare them like numbers. They start at 90 to -// avoid clashing with Scheduler's priorities. -var ImmediatePriority = 99; -var UserBlockingPriority = 98; -var NormalPriority = 97; -var LowPriority = 96; -var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - -var NoPriority = 90; -var shouldYield = Scheduler_shouldYield; -var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. - Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; -var syncQueue = null; -var immediateQueueCallbackNode = null; -var isFlushingSyncQueue = false; -var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. -// This will be the case for modern browsers that support `performance.now`. In -// older browsers, Scheduler falls back to `Date.now`, which returns a Unix -// timestamp. In that case, subtract the module initialization time to simulate -// the behavior of performance.now and keep our times small enough to fit -// within 32 bits. -// TODO: Consider lifting this into Scheduler. - -var now = - initialTimeMs < 10000 - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return ImmediatePriority; +} // Hydration (when unsupported) +var isSuspenseInstancePending = shim; +var isSuspenseInstanceFallback = shim; +var hydrateTextInstance = shim; - case Scheduler_UserBlockingPriority: - return UserBlockingPriority; +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; +var UPDATE_SIGNAL = {}; - case Scheduler_NormalPriority: - return NormalPriority; +{ + Object.freeze(UPDATE_SIGNAL); +} // Counter for uniquely identifying views. +// % 10 === 1 means it is a rootTag. +// % 2 === 0 means it is a Fabric tag. - case Scheduler_LowPriority: - return LowPriority; +var nextReactTag = 3; - case Scheduler_IdlePriority: - return IdlePriority; +function allocateTag() { + var tag = nextReactTag; - default: { - throw Error("Unknown priority level."); - } + if (tag % 10 === 1) { + tag += 2; } -} - -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case ImmediatePriority: - return Scheduler_ImmediatePriority; - - case UserBlockingPriority: - return Scheduler_UserBlockingPriority; - - case NormalPriority: - return Scheduler_NormalPriority; - case LowPriority: - return Scheduler_LowPriority; + nextReactTag = tag + 2; + return tag; +} - case IdlePriority: - return Scheduler_IdlePriority; +function recursivelyUncacheFiberNode(node) { + if (typeof node === "number") { + // Leaf node (eg text) + uncacheFiberNode(node); + } else { + uncacheFiberNode(node._nativeTag); - default: { - throw Error("Unknown priority level."); - } + node._children.forEach(recursivelyUncacheFiberNode); } } - -function runWithPriority(reactPriorityLevel, fn) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(priorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(priorityLevel, callback, options); +function appendInitialChild(parentInstance, child) { + parentInstance._children.push(child); } -function scheduleSyncCallback(callback) { - // Push this callback into an internal queue. We'll flush these either in - // the next tick, or earlier if something calls `flushSyncCallbackQueue`. - if (syncQueue === null) { - syncQueue = [callback]; // TODO: Figure out how to remove this It's only here as a last resort if we - // forget to explicitly flush. +function createInstance( + type, + props, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + var tag = allocateTag(); + var viewConfig = getViewConfigForType(type); - { - // Flush the queue in the next tick. - immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ); + { + for (var key in viewConfig.validAttributes) { + if (props.hasOwnProperty(key)) { + ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( + props[key] + ); + } } - } else { - // Push onto existing queue. Don't need to schedule a callback because - // we already scheduled one when we created the queue. - syncQueue.push(callback); } + + var updatePayload = create(props, viewConfig.validAttributes); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + viewConfig.uiViewClassName, // viewName + rootContainerInstance, // rootTag + updatePayload // props + ); + var component = new ReactNativeFiberHostComponent( + tag, + viewConfig, + internalInstanceHandle + ); + precacheFiberNode(internalInstanceHandle, tag); + updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined + // in the same file but if it's external it can't see the types. + + return component; } -function cancelCallback(callbackNode) { - Scheduler_cancelCallback(callbackNode); -} -function flushSyncCallbackQueue() { - if (immediateQueueCallbackNode !== null) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); +function createTextInstance( + text, + rootContainerInstance, + hostContext, + internalInstanceHandle +) { + if (!hostContext.isInAParentText) { + throw Error("Text strings must be rendered within a component."); } - flushSyncCallbackQueueImpl(); + var tag = allocateTag(); + ReactNativePrivateInterface.UIManager.createView( + tag, // reactTag + "RCTRawText", // viewName + rootContainerInstance, // rootTag + { + text: text + } // props + ); + precacheFiberNode(internalInstanceHandle, tag); + return tag; } +function finalizeInitialChildren( + parentInstance, + type, + props, + rootContainerInstance, + hostContext +) { + // Don't send a no-op message over the bridge. + if (parentInstance._children.length === 0) { + return false; + } // Map from child objects to native tags. + // Either way we need to pass a copy of the Array to prevent it from being frozen. -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && syncQueue !== null) { - // Prevent re-entrancy. - isFlushingSyncQueue = true; - var i = 0; - - { - try { - var _isSync2 = true; - var _queue = syncQueue; - runWithPriority(ImmediatePriority, function() { - for (; i < _queue.length; i++) { - var callback = _queue[i]; + var nativeTags = parentInstance._children.map(function(child) { + return typeof child === "number" + ? child // Leaf node (eg text) + : child._nativeTag; + }); - do { - callback = callback(_isSync2); - } while (callback !== null); - } - }); - syncQueue = null; - } catch (error) { - // If something throws, leave the remaining callbacks on the queue. - if (syncQueue !== null) { - syncQueue = syncQueue.slice(i + 1); - } // Resume flushing in the next tick + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, // containerTag + nativeTags // reactTags + ); + return false; +} +function getRootHostContext(rootContainerInstance) { + return { + isInAParentText: false + }; +} +function getChildHostContext(parentHostContext, type, rootContainerInstance) { + var prevIsInAParentText = parentHostContext.isInAParentText; + var isInAParentText = + type === "AndroidTextInput" || // Android + type === "RCTMultilineTextInputView" || // iOS + type === "RCTSinglelineTextInputView" || // iOS + type === "RCTText" || + type === "RCTVirtualText"; - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ); - throw error; - } finally { - isFlushingSyncQueue = false; - } - } + if (prevIsInAParentText !== isInAParentText) { + return { + isInAParentText: isInAParentText + }; + } else { + return parentHostContext; } } +function getPublicInstance(instance) { + return instance; +} +function prepareForCommit(containerInfo) { + // Noop + return null; +} +function prepareUpdate( + instance, + type, + oldProps, + newProps, + rootContainerInstance, + hostContext +) { + return UPDATE_SIGNAL; +} +function resetAfterCommit(containerInfo) { + // Noop +} +var scheduleTimeout = setTimeout; +var cancelTimeout = clearTimeout; +var noTimeout = -1; +function shouldSetTextContent(type, props) { + // TODO (bvaughn) Revisit this decision. + // Always returning false simplifies the createInstance() implementation, + // But creates an additional child Fiber for raw text children. + // No additional native views are created though. + // It's not clear to me which is better so I'm deferring for now. + // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 + return false; +} // ------------------- +function appendChild(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + var children = parentInstance._children; + var index = children.indexOf(child); -var SyncLanePriority = 15; -var SyncBatchedLanePriority = 14; -var InputDiscreteHydrationLanePriority = 13; -var InputDiscreteLanePriority = 12; -var InputContinuousHydrationLanePriority = 11; -var InputContinuousLanePriority = 10; -var DefaultHydrationLanePriority = 9; -var DefaultLanePriority = 8; -var TransitionHydrationPriority = 7; -var TransitionPriority = 6; -var RetryLanePriority = 5; -var SelectiveHydrationLanePriority = 4; -var IdleHydrationLanePriority = 3; -var IdleLanePriority = 2; -var OffscreenLanePriority = 1; -var NoLanePriority = 0; // Lane values below should be kept in sync with getLabelsForLanes(), used by react-devtools-scheduling-profiler. -// If those values are changed that package should be rebuilt and redeployed. - -var TotalLanes = 31; -var NoLanes = - /* */ - 0; -var NoLane = - /* */ - 0; -var SyncLane = - /* */ - 1; -var SyncBatchedLane = - /* */ - 2; -var InputDiscreteHydrationLane = - /* */ - 4; -var InputDiscreteLane = - /* */ - 8; -var InputContinuousHydrationLane = - /* */ - 16; -var InputContinuousLane = - /* */ - 32; -var DefaultHydrationLane = - /* */ - 64; -var DefaultLane = - /* */ - 128; -var TransitionHydrationLane = - /* */ - 256; -var TransitionLanes = - /* */ - 8388096; -var TransitionLane1 = - /* */ - 512; -var TransitionLane2 = - /* */ - 1024; -var TransitionLane3 = - /* */ - 2048; -var TransitionLane4 = - /* */ - 4096; -var TransitionLane5 = - /* */ - 8192; -var TransitionLane6 = - /* */ - 16384; -var TransitionLane7 = - /* */ - 32768; -var TransitionLane8 = - /* */ - 65536; -var TransitionLane9 = - /* */ - 131072; -var TransitionLane10 = - /* */ - 262144; -var TransitionLane11 = - /* */ - 524288; -var TransitionLane12 = - /* */ - 1048576; -var TransitionLane13 = - /* */ - 2097152; -var TransitionLane14 = - /* */ - 4194304; -var RetryLanes = - /* */ - 125829120; -var RetryLane1 = - /* */ - 8388608; -var RetryLane2 = - /* */ - 16777216; -var RetryLane3 = - /* */ - 33554432; -var RetryLane4 = - /* */ - 67108864; -var SomeRetryLane = RetryLane1; -var SelectiveHydrationLane = - /* */ - 134217728; -var NonIdleLanes = - /* */ - 268435455; -var IdleHydrationLane = - /* */ - 268435456; -var IdleLane = - /* */ - 536870912; -var OffscreenLane = - /* */ - 1073741824; // This function is used for the experimental scheduling profiler (react-devtools-scheduling-profiler) -var NoTimestamp = -1; -var nextTransitionLane = TransitionLane1; -var nextRetryLane = RetryLane1; -// Used by getHighestPriorityLanes and getNextLanes: - -var return_highestLanePriority = DefaultLanePriority; - -function getHighestPriorityLanes(lanes) { - switch (getHighestPriorityLane(lanes)) { - case SyncLane: - return_highestLanePriority = SyncLanePriority; - return SyncLane; - - case SyncBatchedLane: - return_highestLanePriority = SyncBatchedLanePriority; - return SyncBatchedLane; - - case InputDiscreteHydrationLane: - return_highestLanePriority = InputDiscreteHydrationLanePriority; - return InputDiscreteHydrationLane; - - case InputDiscreteLane: - return_highestLanePriority = InputDiscreteLanePriority; - return InputDiscreteLane; - - case InputContinuousHydrationLane: - return_highestLanePriority = InputContinuousHydrationLanePriority; - return InputContinuousHydrationLane; - - case InputContinuousLane: - return_highestLanePriority = InputContinuousLanePriority; - return InputContinuousLane; - - case DefaultHydrationLane: - return_highestLanePriority = DefaultHydrationLanePriority; - return DefaultHydrationLane; - - case DefaultLane: - return_highestLanePriority = DefaultLanePriority; - return DefaultLane; - - case TransitionHydrationLane: - return_highestLanePriority = TransitionHydrationPriority; - return TransitionHydrationLane; - - case TransitionLane1: - case TransitionLane2: - case TransitionLane3: - case TransitionLane4: - case TransitionLane5: - case TransitionLane6: - case TransitionLane7: - case TransitionLane8: - case TransitionLane9: - case TransitionLane10: - case TransitionLane11: - case TransitionLane12: - case TransitionLane13: - case TransitionLane14: - return_highestLanePriority = TransitionPriority; - return lanes & TransitionLanes; - - case RetryLane1: - case RetryLane2: - case RetryLane3: - case RetryLane4: - return_highestLanePriority = RetryLanePriority; - return lanes & RetryLanes; - - case SelectiveHydrationLane: - return_highestLanePriority = SelectiveHydrationLanePriority; - return SelectiveHydrationLane; - - case IdleHydrationLane: - return_highestLanePriority = IdleHydrationLanePriority; - return IdleHydrationLane; - - case IdleLane: - return_highestLanePriority = IdleLanePriority; - return IdleLane; - - case OffscreenLane: - return_highestLanePriority = OffscreenLanePriority; - return OffscreenLane; - - default: - { - error("Should have found matching lanes. This is a bug in React."); - } // This shouldn't be reachable, but as a fallback, return the entire bitmask. + if (index >= 0) { + children.splice(index, 1); + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [index], // moveFromIndices + [children.length - 1], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + children.push(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerTag + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [children.length - 1], // addAtIndices + [] // removeAtIndices + ); + } +} +function appendChildToContainer(parentInstance, child) { + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance, // containerTag + [childTag] // reactTags + ); +} +function commitTextUpdate(textInstance, oldText, newText) { + ReactNativePrivateInterface.UIManager.updateView( + textInstance, // reactTag + "RCTRawText", // viewName + { + text: newText + } // props + ); +} +function commitUpdate( + instance, + updatePayloadTODO, + type, + oldProps, + newProps, + internalInstanceHandle +) { + var viewConfig = instance.viewConfig; + updateFiberProps(instance._nativeTag, newProps); + var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. + // This is an expensive no-op for Android, and causes an unnecessary + // view invalidation for certain components (eg RCTTextInput) on iOS. - return_highestLanePriority = DefaultLanePriority; - return lanes; + if (updatePayload != null) { + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, // reactTag + viewConfig.uiViewClassName, // viewName + updatePayload // props + ); } } +function insertBefore(parentInstance, child, beforeChild) { + var children = parentInstance._children; + var index = children.indexOf(child); // Move existing child or add new child? -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case ImmediatePriority: - return SyncLanePriority; - - case UserBlockingPriority: - return InputContinuousLanePriority; - - case NormalPriority: - case LowPriority: - // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. - return DefaultLanePriority; - - case IdlePriority: - return IdleLanePriority; + if (index >= 0) { + children.splice(index, 1); + var beforeChildIndex = children.indexOf(beforeChild); + children.splice(beforeChildIndex, 0, child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [index], // moveFromIndices + [beforeChildIndex], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [] // removeAtIndices + ); + } else { + var _beforeChildIndex = children.indexOf(beforeChild); - default: - return NoLanePriority; + children.splice(_beforeChildIndex, 0, child); + var childTag = typeof child === "number" ? child : child._nativeTag; + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [childTag], // addChildReactTags + [_beforeChildIndex], // addAtIndices + [] // removeAtIndices + ); } } -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case SyncLanePriority: - case SyncBatchedLanePriority: - return ImmediatePriority; +function insertInContainerBefore(parentInstance, child, beforeChild) { + // TODO (bvaughn): Remove this check when... + // We create a wrapper object for the container in ReactNative render() + // Or we refactor to remove wrapper objects entirely. + // For more info on pros/cons see PR #8560 description. + if (!(typeof parentInstance !== "number")) { + throw Error("Container does not support insertBefore operation"); + } +} +function removeChild(parentInstance, child) { + recursivelyUncacheFiberNode(child); + var children = parentInstance._children; + var index = children.indexOf(child); + children.splice(index, 1); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance._nativeTag, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [index] // removeAtIndices + ); +} +function removeChildFromContainer(parentInstance, child) { + recursivelyUncacheFiberNode(child); + ReactNativePrivateInterface.UIManager.manageChildren( + parentInstance, // containerID + [], // moveFromIndices + [], // moveToIndices + [], // addChildReactTags + [], // addAtIndices + [0] // removeAtIndices + ); +} +function resetTextContent(instance) { + // Noop +} +function hideInstance(instance) { + var viewConfig = instance.viewConfig; + var updatePayload = create( + { + style: { + display: "none" + } + }, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function hideTextInstance(textInstance) { + throw new Error("Not yet implemented."); +} +function unhideInstance(instance, props) { + var viewConfig = instance.viewConfig; + var updatePayload = diff( + Object.assign({}, props, { + style: [ + props.style, + { + display: "none" + } + ] + }), + props, + viewConfig.validAttributes + ); + ReactNativePrivateInterface.UIManager.updateView( + instance._nativeTag, + viewConfig.uiViewClassName, + updatePayload + ); +} +function clearContainer(container) { + // TODO Implement this for React Native + // UIManager does not expose a "remove all" type method. +} +function unhideTextInstance(textInstance, text) { + throw new Error("Not yet implemented."); +} +function makeClientIdInDEV(warnOnAccessInDEV) { + throw new Error("Not yet implemented"); +} +function preparePortalMount(portalInstance) { + // noop +} - case InputDiscreteHydrationLanePriority: - case InputDiscreteLanePriority: - case InputContinuousHydrationLanePriority: - case InputContinuousLanePriority: - return UserBlockingPriority; +// Helpers to patch console.logs to avoid logging during side-effect free +// replaying on render function. This currently only patches the object +// lazily which won't cover if the log function was extracted eagerly. +// We could also eagerly patch the method. +var disabledDepth = 0; +var prevLog; +var prevInfo; +var prevWarn; +var prevError; +var prevGroup; +var prevGroupCollapsed; +var prevGroupEnd; - case DefaultHydrationLanePriority: - case DefaultLanePriority: - case TransitionHydrationPriority: - case TransitionPriority: - case SelectiveHydrationLanePriority: - case RetryLanePriority: - return NormalPriority; +function disabledLog() {} - case IdleHydrationLanePriority: - case IdleLanePriority: - case OffscreenLanePriority: - return IdlePriority; +disabledLog.__reactDisabledLog = true; +function disableLogs() { + { + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 - case NoLanePriority: - return NoPriority; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. - default: { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + /* eslint-enable react-internal/no-production-logging */ } + + disabledDepth++; } } -function getNextLanes(root, wipLanes) { - // Early bailout if there's no pending work left. - var pendingLanes = root.pendingLanes; +function reenableLogs() { + { + disabledDepth--; - if (pendingLanes === NoLanes) { - return_highestLanePriority = NoLanePriority; - return NoLanes; + if (disabledDepth === 0) { + /* eslint-disable react-internal/no-production-logging */ + var props = { + configurable: true, + enumerable: true, + writable: true + }; // $FlowFixMe Flow thinks console is immutable. + + Object.defineProperties(console, { + log: Object.assign({}, props, { + value: prevLog + }), + info: Object.assign({}, props, { + value: prevInfo + }), + warn: Object.assign({}, props, { + value: prevWarn + }), + error: Object.assign({}, props, { + value: prevError + }), + group: Object.assign({}, props, { + value: prevGroup + }), + groupCollapsed: Object.assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: Object.assign({}, props, { + value: prevGroupEnd + }) + }); + /* eslint-enable react-internal/no-production-logging */ + } + + if (disabledDepth < 0) { + error( + "disabledDepth fell below zero. " + + "This is a bug in React. Please file an issue." + ); + } } +} - var nextLanes = NoLanes; - var nextLanePriority = NoLanePriority; - var expiredLanes = root.expiredLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; // Check if any work has expired. +var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; +function describeBuiltInComponentFrame(name, source, ownerFn) { + { + var ownerName = null; - if (expiredLanes !== NoLanes) { - // TODO: Should entangle with SyncLane - nextLanes = expiredLanes; - nextLanePriority = return_highestLanePriority = SyncLanePriority; - } else { - // Do not work on any idle work until all the non-idle work has finished, - // even if the work is suspended. - var nonIdlePendingLanes = pendingLanes & NonIdleLanes; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; + } - if (nonIdlePendingLanes !== NoLanes) { - var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; + return describeComponentFrame(name, source, ownerName); + } +} +var componentFrameCache; - if (nonIdleUnblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; +{ + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); +} +var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - if (nonIdlePingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); - nextLanePriority = return_highestLanePriority; - } - } - } else { - // The only remaining work is Idle. - var unblockedLanes = pendingLanes & ~suspendedLanes; +function describeComponentFrame(name, source, ownerName) { + var sourceInfo = ""; - if (unblockedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(unblockedLanes); - nextLanePriority = return_highestLanePriority; - } else { - if (pingedLanes !== NoLanes) { - nextLanes = getHighestPriorityLanes(pingedLanes); - nextLanePriority = return_highestLanePriority; + if (source) { + var path = source.fileName; + var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: + // prefer "folder/index.js" instead of just "index.js". + + if (/^index\./.test(fileName)) { + var match = path.match(BEFORE_SLASH_RE); + + if (match) { + var pathBeforeSlash = match[1]; + + if (pathBeforeSlash) { + var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); + fileName = folderName + "/" + fileName; } } } - } - if (nextLanes === NoLanes) { - // This should only be reachable if we're suspended - // TODO: Consider warning in this path if a fallback timer is not scheduled. - return NoLanes; - } // If we're already in the middle of a render, switching lanes will interrupt - // it and we'll lose our progress. We should only do this if the new lanes are - // higher priority. + sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; + } else if (ownerName) { + sourceInfo = " (created by " + ownerName + ")"; + } - if ( - wipLanes !== NoLanes && - wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't - // bother waiting until the root is complete. - (wipLanes & suspendedLanes) === NoLanes - ) { - getHighestPriorityLanes(wipLanes); - var wipLanePriority = return_highestLanePriority; + return "\n in " + (name || "Unknown") + sourceInfo; +} - if ( - nextLanePriority <= wipLanePriority || // Default priority updates should not interrupt transition updates. The - // only difference between default updates and transition updates is that - // default updates do not support refresh transitions. - (nextLanePriority === DefaultLanePriority && - wipLanePriority === TransitionPriority) - ) { - // Keep working on the existing in-progress tree. Do not interrupt. - return wipLanes; - } else { - return_highestLanePriority = nextLanePriority; +function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeFunctionComponentFrame(ctor, source, ownerFn); + } +} +function describeFunctionComponentFrame(fn, source, ownerFn) { + { + if (!fn) { + return ""; } - } // Check for entangled lanes and add them to the batch. - // - // A lane is said to be entangled with another when it's not allowed to render - // in a batch that does not also include the other lane. Typically we do this - // when multiple updates have the same source, and we only want to respond to - // the most recent event from that source. - // - // Note that we apply entanglements *after* checking for partial work above. - // This means that if a lane is entangled during an interleaved event while - // it's already rendering, we won't interrupt it. This is intentional, since - // entanglement is usually "best effort": we'll try our best to render the - // lanes in the same batch, but it's not worth throwing out partially - // completed work in order to do it. - // TODO: Reconsider this. The counter-argument is that the partial work - // represents an intermediate state, which we don't want to show to the user. - // And by spending extra time finishing it, we're increasing the amount of - // time it takes to show the final state, which is what they are actually - // waiting for. - // - // For those exceptions where entanglement is semantically important, like - // useMutableSource, we should ensure that there is no partial work at the - // time we apply the entanglement. - - var entangledLanes = root.entangledLanes; - if (entangledLanes !== NoLanes) { - var entanglements = root.entanglements; - var lanes = nextLanes & entangledLanes; + var name = fn.displayName || fn.name || null; + var ownerName = null; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - nextLanes |= entanglements[index]; - lanes &= ~lane; + if (ownerFn) { + ownerName = ownerFn.displayName || ownerFn.name || null; } - } - return nextLanes; + return describeComponentFrame(name, source, ownerName); + } } -function getMostRecentEventTime(root, lanes) { - var eventTimes = root.eventTimes; - var mostRecentEventTime = NoTimestamp; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var eventTime = eventTimes[index]; +function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } - if (eventTime > mostRecentEventTime) { - mostRecentEventTime = eventTime; + if (typeof type === "function") { + { + return describeFunctionComponentFrame(type, source, ownerFn); } - - lanes &= ~lane; } - return mostRecentEventTime; -} + if (typeof type === "string") { + return describeBuiltInComponentFrame(type, source, ownerFn); + } -function computeExpirationTime(lane, currentTime) { - // TODO: Expiration heuristic is constant per lane, so could use a map. - getHighestPriorityLanes(lane); - var priority = return_highestLanePriority; + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense", source, ownerFn); - if (priority >= InputContinuousLanePriority) { - // User interactions should expire slightly more quickly. - // - // NOTE: This is set to the corresponding constant as in Scheduler.js. When - // we made it larger, a product metric in www regressed, suggesting there's - // a user interaction that's being starved by a series of synchronous - // updates. If that theory is correct, the proper solution is to fix the - // starvation. However, this scenario supports the idea that expiration - // times are an important safeguard when starvation does happen. - // - // Also note that, in the case of user input specifically, this will soon no - // longer be an issue because we plan to make user input synchronous by - // default (until you enter `startTransition`, of course.) - // - // If weren't planning to make these updates synchronous soon anyway, I - // would probably make this number a configurable parameter. - return currentTime + 250; - } else if (priority >= TransitionPriority) { - return currentTime + 5000; - } else { - // Anything idle priority or lower should never expire. - return NoTimestamp; + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); } -} -function markStarvedLanesAsExpired(root, currentTime) { - // TODO: This gets called every time we yield. We can optimize by storing - // the earliest expiration time on the root. Then use that to quickly bail out - // of this function. - var pendingLanes = root.pendingLanes; - var suspendedLanes = root.suspendedLanes; - var pingedLanes = root.pingedLanes; - var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their - // expiration time. If so, we'll assume the update is being starved and mark - // it as expired to force it to finish. + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render, source, ownerFn); - var lanes = pendingLanes; + case REACT_MEMO_TYPE: + // Memo may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - var expirationTime = expirationTimes[index]; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; - if (expirationTime === NoTimestamp) { - // Found a pending lane with no expiration time. If it's not suspended, or - // if it's pinged, assume it's CPU-bound. Compute a new expiration time - // using the current time. - if ( - (lane & suspendedLanes) === NoLanes || - (lane & pingedLanes) !== NoLanes - ) { - // Assumes timestamps are monotonically increasing. - expirationTimes[index] = computeExpirationTime(lane, currentTime); + try { + // Lazy may contain any component type so we recursively resolve it. + return describeUnknownElementTypeFrameInDEV( + init(payload), + source, + ownerFn + ); + } catch (x) {} } - } else if (expirationTime <= currentTime) { - // This lane expired - root.expiredLanes |= lane; } - - lanes &= ~lane; } -} // This returns the highest priority pending lanes regardless of whether they -function getLanesToRetrySynchronouslyOnError(root) { - var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - if (everythingButOffscreen !== NoLanes) { - return everythingButOffscreen; - } + return ""; +} - if (everythingButOffscreen & OffscreenLane) { - return OffscreenLane; - } +var loggedTypeFailures = {}; +var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; - return NoLanes; -} -function returnNextLanesPriority() { - return return_highestLanePriority; -} -function includesNonIdleWork(lanes) { - return (lanes & NonIdleLanes) !== NoLanes; -} -function includesOnlyRetries(lanes) { - return (lanes & RetryLanes) === lanes; -} -function includesOnlyTransitions(lanes) { - return (lanes & TransitionLanes) === lanes; +function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack = describeUnknownElementTypeFrameInDEV( + element.type, + element._source, + owner ? owner.type : null + ); + ReactDebugCurrentFrame.setExtraStackFrame(stack); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } + } } -function isTransitionLane(lane) { - return (lane & TransitionLanes) !== 0; -} // To ensure consistency across multiple updates in the same event, this should -// be a pure function, so that it always returns the same lane for given inputs. - -function findUpdateLane(lanePriority) { - switch (lanePriority) { - case NoLanePriority: - break; - case SyncLanePriority: - return SyncLane; +function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + // $FlowFixMe This is okay but Flow doesn't know it. + var has = Function.call.bind(Object.prototype.hasOwnProperty); - case SyncBatchedLanePriority: - return SyncBatchedLane; + for (var typeSpecName in typeSpecs) { + if (has(typeSpecs, typeSpecName)) { + var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. - case InputDiscreteLanePriority: - return InputDiscreteLane; + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error( + (componentName || "React class") + + ": " + + location + + " type `" + + typeSpecName + + "` is invalid; " + + "it must be a function, usually from the `prop-types` package, but received `" + + typeof typeSpecs[typeSpecName] + + "`." + + "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." + ); + err.name = "Invariant Violation"; + throw err; + } - case InputContinuousLanePriority: - return InputContinuousLane; + error$1 = typeSpecs[typeSpecName]( + values, + typeSpecName, + componentName, + location, + null, + "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" + ); + } catch (ex) { + error$1 = ex; + } - case DefaultLanePriority: - return DefaultLane; + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); - case TransitionPriority: // Should be handled by findTransitionLane instead + error( + "%s: type specification of %s" + + " `%s` is invalid; the type checker " + + "function must return `null` or an `Error` but returned a %s. " + + "You may have forgotten to pass an argument to the type checker " + + "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + + "shape all require an argument).", + componentName || "React class", + location, + typeSpecName, + typeof error$1 + ); - case RetryLanePriority: - // Should be handled by findRetryLane instead - break; + setCurrentlyValidatingElement(null); + } - case IdleLanePriority: - return IdleLane; - } + if ( + error$1 instanceof Error && + !(error$1.message in loggedTypeFailures) + ) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); - { - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); - } -} -function claimNextTransitionLane() { - // Cycle through the lanes, assigning each new transition to the next lane. - // In most cases, this means every transition gets its own lane, until we - // run out of lanes and cycle back to the beginning. - var lane = nextTransitionLane; - nextTransitionLane <<= 1; + error("Failed %s type: %s", location, error$1.message); - if ((nextTransitionLane & TransitionLanes) === 0) { - nextTransitionLane = TransitionLane1; + setCurrentlyValidatingElement(null); + } + } + } } - - return lane; } -function claimNextRetryLane() { - var lane = nextRetryLane; - nextRetryLane <<= 1; - if ((nextRetryLane & RetryLanes) === 0) { - nextRetryLane = RetryLane1; - } +var valueStack = []; +var fiberStack; - return lane; +{ + fiberStack = []; } -function getHighestPriorityLane(lanes) { - return lanes & -lanes; -} +var index = -1; -function pickArbitraryLane(lanes) { - // This wrapper function gets inlined. Only exists so to communicate that it - // doesn't matter which bit is selected; you can pick any bit without - // affecting the algorithms where its used. Here I'm using - // getHighestPriorityLane because it requires the fewest operations. - return getHighestPriorityLane(lanes); +function createCursor(defaultValue) { + return { + current: defaultValue + }; } -function pickArbitraryLaneIndex(lanes) { - return 31 - clz32(lanes); -} +function pop(cursor, fiber) { + if (index < 0) { + { + error("Unexpected pop."); + } -function laneToIndex(lane) { - return pickArbitraryLaneIndex(lane); -} + return; + } -function includesSomeLane(a, b) { - return (a & b) !== NoLanes; -} -function isSubsetOfLanes(set, subset) { - return (set & subset) === subset; -} -function mergeLanes(a, b) { - return a | b; -} -function removeLanes(set, subset) { - return set & ~subset; -} -function intersectLanes(a, b) { - return a & b; -} // Seems redundant, but it changes the type from a single lane (used for -// updates) to a group of lanes (used for flushing work). + { + if (fiber !== fiberStack[index]) { + error("Unexpected Fiber popped."); + } + } -function laneToLanes(lane) { - return lane; -} -function createLaneMap(initial) { - // Intentionally pushing one by one. - // https://v8.dev/blog/elements-kinds#avoid-creating-holes - var laneMap = []; + cursor.current = valueStack[index]; + valueStack[index] = null; - for (var i = 0; i < TotalLanes; i++) { - laneMap.push(initial); + { + fiberStack[index] = null; } - return laneMap; + index--; } -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update - // could unblock them. Clear the suspended lanes so that we can try rendering - // them again. - // - // TODO: We really only need to unsuspend only lanes that are in the - // `subtreeLanes` of the updated fiber, or the update lanes of the return - // path. This would exclude suspended updates in an unrelated sibling tree, - // since there's no way for this update to unblock it. - // - // We don't do this if the incoming update is idle, because we never process - // idle updates until after all the regular updates have finished; there's no - // way it could unblock a transition. - if (updateLane !== IdleLane) { - root.suspendedLanes = NoLanes; - root.pingedLanes = NoLanes; - } +function push(cursor, value, fiber) { + index++; + valueStack[index] = cursor.current; - var eventTimes = root.eventTimes; - var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most - // recent event, and we assume time is monotonically increasing. + { + fiberStack[index] = fiber; + } - eventTimes[index] = eventTime; + cursor.current = value; } -function markRootSuspended(root, suspendedLanes) { - root.suspendedLanes |= suspendedLanes; - root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. - var expirationTimes = root.expirationTimes; - var lanes = suspendedLanes; +var warnedAboutMissingGetChildContext; - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootPinged(root, pingedLanes, eventTime) { - root.pingedLanes |= root.suspendedLanes & pingedLanes; -} -function markRootExpired(root, expiredLanes) { - root.expiredLanes |= expiredLanes & root.pendingLanes; -} -function hasDiscreteLanes(lanes) { - return (lanes & InputDiscreteLane) !== NoLanes; -} -function markRootMutableRead(root, updateLane) { - root.mutableReadLanes |= updateLane & root.pendingLanes; +{ + warnedAboutMissingGetChildContext = {}; } -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; // Let's try everything again - - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - var entanglements = root.entanglements; - var eventTimes = root.eventTimes; - var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work +var emptyContextObject = {}; - var lanes = noLongerPendingLanes; +{ + Object.freeze(emptyContextObject); +} // A cursor to the current merged context object on the stack. - while (lanes > 0) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; - entanglements[index] = NoLanes; - eventTimes[index] = NoTimestamp; - expirationTimes[index] = NoTimestamp; - lanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - // In addition to entangling each of the given lanes with each other, we also - // have to consider _transitive_ entanglements. For each lane that is already - // entangled with *any* of the given lanes, that lane is now transitively - // entangled with *all* the given lanes. - // - // Translated: If C is entangled with A, then entangling A with B also - // entangles C with B. - // - // If this is hard to grasp, it might help to intentionally break this - // function and look at the tests that fail in ReactTransition-test.js. Try - // commenting out one of the conditions below. - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - var entanglements = root.entanglements; - var lanes = rootEntangledLanes; +var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. - while (lanes) { - var index = pickArbitraryLaneIndex(lanes); - var lane = 1 << index; +var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. +// We use this to get access to the parent context after we have already +// pushed the next context provider, and now need to merge their contexts. - if ( - // Is this one of the newly entangled lanes? - (lane & entangledLanes) | // Is this lane transitively entangled with the newly entangled lanes? - (entanglements[index] & entangledLanes) - ) { - entanglements[index] |= entangledLanes; - } +var previousContext = emptyContextObject; - lanes &= ~lane; +function getUnmaskedContext( + workInProgress, + Component, + didPushOwnContextIfProvider +) { + { + if (didPushOwnContextIfProvider && isContextProvider(Component)) { + // If the fiber is a context provider itself, when we read its context + // we may have already pushed its own child context on the stack. A context + // provider should not "see" its own child context. Therefore we read the + // previous (parent) context instead for a context provider. + return previousContext; + } + + return contextStackCursor.current; } } -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. -// Based on: -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - -var log = Math.log; -var LN2 = Math.LN2; -function clz32Fallback(lanes) { - if (lanes === 0) { - return 32; +function cacheContext(workInProgress, unmaskedContext, maskedContext) { + { + var instance = workInProgress.stateNode; + instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; + instance.__reactInternalMemoizedMaskedChildContext = maskedContext; } - - return (31 - ((log(lanes) / LN2) | 0)) | 0; } -// Intentionally not named imports because Rollup would use dynamic dispatch for -var Scheduler_now$1 = Scheduler.unstable_now; +function getMaskedContext(workInProgress, unmaskedContext) { + { + var type = workInProgress.type; + var contextTypes = type.contextTypes; -{ - // Provide explicit error message when production+profiling bundle of e.g. - // react-dom is used with production (non-profiling) bundle of - // scheduler/tracing - if ( - !( - tracing.__interactionsRef != null && - tracing.__interactionsRef.current != null - ) - ) { - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); - } -} -var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. + if (!contextTypes) { + return emptyContextObject; + } // Avoid recreating masked context unless unmasked context has changed. + // Failing to do this will result in unnecessary calls to componentWillReceiveProps. + // This may trigger infinite loops if componentWillReceiveProps calls setState. -// can re-export everything from this module. + var instance = workInProgress.stateNode; -function shim() { - { - 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; + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) { + return instance.__reactInternalMemoizedMaskedChildContext; + } -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get; -var UPDATE_SIGNAL = {}; + var context = {}; -{ - Object.freeze(UPDATE_SIGNAL); -} // Counter for uniquely identifying views. -// % 10 === 1 means it is a rootTag. -// % 2 === 0 means it is a Fabric tag. + for (var key in contextTypes) { + context[key] = unmaskedContext[key]; + } -var nextReactTag = 3; + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(contextTypes, context, "context", name); + } // Cache unmasked context so we can avoid recreating masked context unless necessary. + // Context is created before the class component is instantiated so check for instance. -function allocateTag() { - var tag = nextReactTag; + if (instance) { + cacheContext(workInProgress, unmaskedContext, context); + } - if (tag % 10 === 1) { - tag += 2; + return context; } +} - nextReactTag = tag + 2; - return tag; +function hasContextChanged() { + { + return didPerformWorkStackCursor.current; + } } -function recursivelyUncacheFiberNode(node) { - if (typeof node === "number") { - // Leaf node (eg text) - uncacheFiberNode(node); - } else { - uncacheFiberNode(node._nativeTag); +function isContextProvider(type) { + { + var childContextTypes = type.childContextTypes; + return childContextTypes !== null && childContextTypes !== undefined; + } +} - node._children.forEach(recursivelyUncacheFiberNode); +function popContext(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); } } -function appendInitialChild(parentInstance, child) { - parentInstance._children.push(child); + +function popTopLevelContextObject(fiber) { + { + pop(didPerformWorkStackCursor, fiber); + pop(contextStackCursor, fiber); + } } -function createInstance( - type, - props, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - var tag = allocateTag(); - var viewConfig = getViewConfigForType(type); +function pushTopLevelContextObject(fiber, context, didChange) { { - for (var key in viewConfig.validAttributes) { - if (props.hasOwnProperty(key)) { - ReactNativePrivateInterface.deepFreezeAndThrowOnMutationInDev( - props[key] - ); - } + if (!(contextStackCursor.current === emptyContextObject)) { + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); } + + push(contextStackCursor, context, fiber); + push(didPerformWorkStackCursor, didChange, fiber); } +} - var updatePayload = create(props, viewConfig.validAttributes); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - viewConfig.uiViewClassName, // viewName - rootContainerInstance, // rootTag - updatePayload // props - ); - var component = new ReactNativeFiberHostComponent( - tag, - viewConfig, - internalInstanceHandle - ); - precacheFiberNode(internalInstanceHandle, tag); - updateFiberProps(tag, props); // Not sure how to avoid this cast. Flow is okay if the component is defined - // in the same file but if it's external it can't see the types. +function processChildContext(fiber, type, parentContext) { + { + var instance = fiber.stateNode; + var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. + // It has only been added in Fiber to match the (unintentional) behavior in Stack. - return component; -} -function createTextInstance( - text, - rootContainerInstance, - hostContext, - internalInstanceHandle -) { - if (!hostContext.isInAParentText) { - throw Error("Text strings must be rendered within a component."); - } + if (typeof instance.getChildContext !== "function") { + { + var componentName = getComponentName(type) || "Unknown"; - var tag = allocateTag(); - ReactNativePrivateInterface.UIManager.createView( - tag, // reactTag - "RCTRawText", // viewName - rootContainerInstance, // rootTag - { - text: text - } // props - ); - precacheFiberNode(internalInstanceHandle, tag); - return tag; -} -function finalizeInitialChildren( - parentInstance, - type, - props, - rootContainerInstance, - hostContext -) { - // Don't send a no-op message over the bridge. - if (parentInstance._children.length === 0) { - return false; - } // Map from child objects to native tags. - // Either way we need to pass a copy of the Array to prevent it from being frozen. + if (!warnedAboutMissingGetChildContext[componentName]) { + warnedAboutMissingGetChildContext[componentName] = true; - var nativeTags = parentInstance._children.map(function(child) { - return typeof child === "number" - ? child // Leaf node (eg text) - : child._nativeTag; - }); + error( + "%s.childContextTypes is specified but there is no getChildContext() method " + + "on the instance. You can either define getChildContext() on %s or remove " + + "childContextTypes from it.", + componentName, + componentName + ); + } + } - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, // containerTag - nativeTags // reactTags - ); - return false; -} -function getRootHostContext(rootContainerInstance) { - return { - isInAParentText: false - }; -} -function getChildHostContext(parentHostContext, type, rootContainerInstance) { - var prevIsInAParentText = parentHostContext.isInAParentText; - var isInAParentText = - type === "AndroidTextInput" || // Android - type === "RCTMultilineTextInputView" || // iOS - type === "RCTSinglelineTextInputView" || // iOS - type === "RCTText" || - type === "RCTVirtualText"; + return parentContext; + } - if (prevIsInAParentText !== isInAParentText) { - return { - isInAParentText: isInAParentText - }; - } else { - return parentHostContext; + var childContext = instance.getChildContext(); + + for (var contextKey in childContext) { + if (!(contextKey in childContextTypes)) { + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + } + } + + { + var name = getComponentName(type) || "Unknown"; + checkPropTypes(childContextTypes, childContext, "child context", name); + } + + return Object.assign({}, parentContext, childContext); } } -function getPublicInstance(instance) { - return instance; -} -function prepareForCommit(containerInfo) { - // Noop - return null; -} -function prepareUpdate( - instance, - type, - oldProps, - newProps, - rootContainerInstance, - hostContext -) { - return UPDATE_SIGNAL; -} -function resetAfterCommit(containerInfo) { - // Noop -} -var scheduleTimeout = setTimeout; -var cancelTimeout = clearTimeout; -var noTimeout = -1; -function shouldSetTextContent(type, props) { - // TODO (bvaughn) Revisit this decision. - // Always returning false simplifies the createInstance() implementation, - // But creates an additional child Fiber for raw text children. - // No additional native views are created though. - // It's not clear to me which is better so I'm deferring for now. - // More context @ github.com/facebook/react/pull/8560#discussion_r92111303 - return false; -} -function appendChild(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - var children = parentInstance._children; - var index = children.indexOf(child); - if (index >= 0) { - children.splice(index, 1); - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [index], // moveFromIndices - [children.length - 1], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - children.push(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerTag - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [children.length - 1], // addAtIndices - [] // removeAtIndices +function pushContextProvider(workInProgress) { + { + var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. + // If the instance does not exist yet, we will push null at first, + // and replace it on the stack later when invalidating the context. + + var memoizedMergedChildContext = + (instance && instance.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; // Remember the parent context so we can merge with it later. + // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + + previousContext = contextStackCursor.current; + push(contextStackCursor, memoizedMergedChildContext, workInProgress); + push( + didPerformWorkStackCursor, + didPerformWorkStackCursor.current, + workInProgress ); + return true; } } -function appendChildToContainer(parentInstance, child) { - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance, // containerTag - [childTag] // reactTags - ); -} -function commitTextUpdate(textInstance, oldText, newText) { - ReactNativePrivateInterface.UIManager.updateView( - textInstance, // reactTag - "RCTRawText", // viewName - { - text: newText - } // props - ); -} -function commitUpdate( - instance, - updatePayloadTODO, - type, - oldProps, - newProps, - internalInstanceHandle -) { - var viewConfig = instance.viewConfig; - updateFiberProps(instance._nativeTag, newProps); - var updatePayload = diff(oldProps, newProps, viewConfig.validAttributes); // Avoid the overhead of bridge calls if there's no update. - // This is an expensive no-op for Android, and causes an unnecessary - // view invalidation for certain components (eg RCTTextInput) on iOS. - if (updatePayload != null) { - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, // reactTag - viewConfig.uiViewClassName, // viewName - updatePayload // props - ); +function invalidateContextProvider(workInProgress, type, didChange) { + { + var instance = workInProgress.stateNode; + + if (!instance) { + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + } + + if (didChange) { + // Merge parent and own context. + // Skip this if we're not updating due to sCU. + // This avoids unnecessarily recomputing memoized values. + var mergedContext = processChildContext( + workInProgress, + type, + previousContext + ); + instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. + // It is important to unwind the context in the reverse order. + + pop(didPerformWorkStackCursor, workInProgress); + pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + + push(contextStackCursor, mergedContext, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } else { + pop(didPerformWorkStackCursor, workInProgress); + push(didPerformWorkStackCursor, didChange, workInProgress); + } } } -function insertBefore(parentInstance, child, beforeChild) { - var children = parentInstance._children; - var index = children.indexOf(child); // Move existing child or add new child? - if (index >= 0) { - children.splice(index, 1); - var beforeChildIndex = children.indexOf(beforeChild); - children.splice(beforeChildIndex, 0, child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [index], // moveFromIndices - [beforeChildIndex], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [] // removeAtIndices - ); - } else { - var _beforeChildIndex = children.indexOf(beforeChild); +function findCurrentUnmaskedContext(fiber) { + { + // Currently this is only used with renderSubtreeIntoContainer; not sure if it + // makes sense elsewhere + if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { + throw Error( + "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." + ); + } - children.splice(_beforeChildIndex, 0, child); - var childTag = typeof child === "number" ? child : child._nativeTag; - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [childTag], // addChildReactTags - [_beforeChildIndex], // addAtIndices - [] // removeAtIndices - ); + var node = fiber; + + do { + switch (node.tag) { + case HostRoot: + return node.stateNode.context; + + case ClassComponent: { + var Component = node.type; + + if (isContextProvider(Component)) { + return node.stateNode.__reactInternalMemoizedMergedChildContext; + } + + break; + } + } + + node = node.return; + } while (node !== null); + + { + throw Error( + "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." + ); + } } } -function insertInContainerBefore(parentInstance, child, beforeChild) { - // TODO (bvaughn): Remove this check when... - // We create a wrapper object for the container in ReactNative render() - // Or we refactor to remove wrapper objects entirely. - // For more info on pros/cons see PR #8560 description. - if (!(typeof parentInstance !== "number")) { - throw Error("Container does not support insertBefore operation"); + +var LegacyRoot = 0; +var BlockingRoot = 1; +var ConcurrentRoot = 2; + +var rendererID = null; +var injectedHook = null; +var hasLoggedError = false; +var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; +function injectInternals(internals) { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { + // No DevTools + return false; } -} -function removeChild(parentInstance, child) { - recursivelyUncacheFiberNode(child); - var children = parentInstance._children; - var index = children.indexOf(child); - children.splice(index, 1); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance._nativeTag, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [index] // removeAtIndices - ); -} -function removeChildFromContainer(parentInstance, child) { - recursivelyUncacheFiberNode(child); - ReactNativePrivateInterface.UIManager.manageChildren( - parentInstance, // containerID - [], // moveFromIndices - [], // moveToIndices - [], // addChildReactTags - [], // addAtIndices - [0] // removeAtIndices - ); -} -function resetTextContent(instance) { - // Noop -} -function hideInstance(instance) { - var viewConfig = instance.viewConfig; - var updatePayload = create( - { - style: { - display: "none" - } - }, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function hideTextInstance(textInstance) { - throw new Error("Not yet implemented."); -} -function unhideInstance(instance, props) { - var viewConfig = instance.viewConfig; - var updatePayload = diff( - Object.assign({}, props, { - style: [ - props.style, - { - display: "none" - } - ] - }), - props, - viewConfig.validAttributes - ); - ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, - viewConfig.uiViewClassName, - updatePayload - ); -} -function clearContainer(container) { - // TODO Implement this for React Native - // UIManager does not expose a "remove all" type method. -} -function unhideTextInstance(textInstance, text) { - throw new Error("Not yet implemented."); -} -function makeClientIdInDEV(warnOnAccessInDEV) { - throw new Error("Not yet implemented"); -} -function preparePortalMount(portalInstance) { - // noop -} -// Helpers to patch console.logs to avoid logging during side-effect free -// replaying on render function. This currently only patches the object -// lazily which won't cover if the log function was extracted eagerly. -// We could also eagerly patch the method. -var disabledDepth = 0; -var prevLog; -var prevInfo; -var prevWarn; -var prevError; -var prevGroup; -var prevGroupCollapsed; -var prevGroupEnd; + var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; -function disabledLog() {} + if (hook.isDisabled) { + // This isn't a real property on the hook, but it can be set to opt out + // of DevTools integration and associated warnings and logs. + // https://github.com/facebook/react/issues/3877 + return true; + } -disabledLog.__reactDisabledLog = true; -function disableLogs() { - { - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - prevLog = console.log; - prevInfo = console.info; - prevWarn = console.warn; - prevError = console.error; - prevGroup = console.group; - prevGroupCollapsed = console.groupCollapsed; - prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099 + if (!hook.supportsFiber) { + { + error( + "The installed version of React DevTools is too old and will not work " + + "with the current version of React. Please update React DevTools. " + + "https://reactjs.org/link/react-devtools" + ); + } // DevTools exists, even though it doesn't support Fiber. - var props = { - configurable: true, - enumerable: true, - value: disabledLog, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. + return true; + } - Object.defineProperties(console, { - info: props, - log: props, - warn: props, - error: props, - group: props, - groupCollapsed: props, - groupEnd: props - }); - /* eslint-enable react-internal/no-production-logging */ + try { + rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + + injectedHook = hook; + } catch (err) { + // Catch all errors because it is unsafe to throw during initialization. + { + error("React instrumentation encountered an error: %s.", err); } + } // DevTools exists - disabledDepth++; - } + return true; } -function reenableLogs() { +function onScheduleRoot(root, children) { { - disabledDepth--; - - if (disabledDepth === 0) { - /* eslint-disable react-internal/no-production-logging */ - var props = { - configurable: true, - enumerable: true, - writable: true - }; // $FlowFixMe Flow thinks console is immutable. - - Object.defineProperties(console, { - log: Object.assign({}, props, { - value: prevLog - }), - info: Object.assign({}, props, { - value: prevInfo - }), - warn: Object.assign({}, props, { - value: prevWarn - }), - error: Object.assign({}, props, { - value: prevError - }), - group: Object.assign({}, props, { - value: prevGroup - }), - groupCollapsed: Object.assign({}, props, { - value: prevGroupCollapsed - }), - groupEnd: Object.assign({}, props, { - value: prevGroupEnd - }) - }); - /* eslint-enable react-internal/no-production-logging */ - } + if ( + injectedHook && + typeof injectedHook.onScheduleFiberRoot === "function" + ) { + try { + injectedHook.onScheduleFiberRoot(rendererID, root, children); + } catch (err) { + if (!hasLoggedError) { + hasLoggedError = true; - if (disabledDepth < 0) { - error( - "disabledDepth fell below zero. " + - "This is a bug in React. Please file an issue." - ); + error("React instrumentation encountered an error: %s", err); + } + } } } } +function onCommitRoot(root, priorityLevel) { + if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { + try { + var didError = (root.current.flags & DidCapture) === DidCapture; -var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; -function describeBuiltInComponentFrame(name, source, ownerFn) { - { - var ownerName = null; + if (enableProfilerTimer) { + injectedHook.onCommitFiberRoot( + rendererID, + root, + priorityLevel, + didError + ); + } else { + injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); + } + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; + error("React instrumentation encountered an error: %s", err); + } + } } - - return describeComponentFrame(name, source, ownerName); } } -var componentFrameCache; - -{ - var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; - componentFrameCache = new PossiblyWeakMap(); -} -var BEFORE_SLASH_RE = /^(.*)[\\\/]/; - -function describeComponentFrame(name, source, ownerName) { - var sourceInfo = ""; - - if (source) { - var path = source.fileName; - var fileName = path.replace(BEFORE_SLASH_RE, ""); // In DEV, include code for a common special case: - // prefer "folder/index.js" instead of just "index.js". - - if (/^index\./.test(fileName)) { - var match = path.match(BEFORE_SLASH_RE); - - if (match) { - var pathBeforeSlash = match[1]; +function onCommitUnmount(fiber) { + if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { + try { + injectedHook.onCommitFiberUnmount(rendererID, fiber); + } catch (err) { + { + if (!hasLoggedError) { + hasLoggedError = true; - if (pathBeforeSlash) { - var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, ""); - fileName = folderName + "/" + fileName; + error("React instrumentation encountered an error: %s", err); } } } + } +} - sourceInfo = " (at " + fileName + ":" + source.lineNumber + ")"; - } else if (ownerName) { - sourceInfo = " (created by " + ownerName + ")"; - } - - return "\n in " + (name || "Unknown") + sourceInfo; -} +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_now = Scheduler.unstable_now; -function describeClassComponentFrame(ctor, source, ownerFn) { - { - return describeFunctionComponentFrame(ctor, source, ownerFn); +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); } } -function describeFunctionComponentFrame(fn, source, ownerFn) { - { - if (!fn) { - return ""; - } +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. - var name = fn.displayName || fn.name || null; - var ownerName = null; +var ImmediatePriority = 99; +var UserBlockingPriority = 98; +var NormalPriority = 97; +var LowPriority = 96; +var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only. - if (ownerFn) { - ownerName = ownerFn.displayName || ownerFn.name || null; - } +var NoPriority = 90; +var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. - return describeComponentFrame(name, source, ownerName); - } -} +var SyncLanePriority = 15; +var SyncBatchedLanePriority = 14; +var InputDiscreteHydrationLanePriority = 13; +var InputDiscreteLanePriority = 12; +var InputContinuousHydrationLanePriority = 11; +var InputContinuousLanePriority = 10; +var DefaultHydrationLanePriority = 9; +var DefaultLanePriority = 8; +var TransitionHydrationPriority = 7; +var TransitionPriority = 6; +var RetryLanePriority = 5; +var SelectiveHydrationLanePriority = 4; +var IdleHydrationLanePriority = 3; +var IdleLanePriority = 2; +var OffscreenLanePriority = 1; +var NoLanePriority = 0; +var TotalLanes = 31; +var NoLanes = + /* */ + 0; +var NoLane = + /* */ + 0; +var SyncLane = + /* */ + 1; +var SyncBatchedLane = + /* */ + 2; +var InputDiscreteHydrationLane = + /* */ + 4; +var InputDiscreteLanes = + /* */ + 24; +var InputContinuousHydrationLane = + /* */ + 32; +var InputContinuousLanes = + /* */ + 192; +var DefaultHydrationLane = + /* */ + 256; +var DefaultLanes = + /* */ + 3584; +var TransitionHydrationLane = + /* */ + 4096; +var TransitionLanes = + /* */ + 4186112; +var RetryLanes = + /* */ + 62914560; +var SomeRetryLane = + /* */ + 33554432; +var SelectiveHydrationLane = + /* */ + 67108864; +var NonIdleLanes = + /* */ + 134217727; +var IdleHydrationLane = + /* */ + 134217728; +var IdleLanes = + /* */ + 805306368; +var OffscreenLane = + /* */ + 1073741824; +var NoTimestamp = -1; +// Used by getHighestPriorityLanes and getNextLanes: -function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { - if (type == null) { - return ""; +var return_highestLanePriority = DefaultLanePriority; + +function getHighestPriorityLanes(lanes) { + if ((SyncLane & lanes) !== NoLanes) { + return_highestLanePriority = SyncLanePriority; + return SyncLane; } - if (typeof type === "function") { - { - return describeFunctionComponentFrame(type, source, ownerFn); - } + if ((SyncBatchedLane & lanes) !== NoLanes) { + return_highestLanePriority = SyncBatchedLanePriority; + return SyncBatchedLane; } - if (typeof type === "string") { - return describeBuiltInComponentFrame(type, source, ownerFn); + if ((InputDiscreteHydrationLane & lanes) !== NoLanes) { + return_highestLanePriority = InputDiscreteHydrationLanePriority; + return InputDiscreteHydrationLane; } - switch (type) { - case REACT_SUSPENSE_TYPE: - return describeBuiltInComponentFrame("Suspense", source, ownerFn); + var inputDiscreteLanes = InputDiscreteLanes & lanes; - case REACT_SUSPENSE_LIST_TYPE: - return describeBuiltInComponentFrame("SuspenseList", source, ownerFn); + if (inputDiscreteLanes !== NoLanes) { + return_highestLanePriority = InputDiscreteLanePriority; + return inputDiscreteLanes; } - if (typeof type === "object") { - switch (type.$$typeof) { - case REACT_FORWARD_REF_TYPE: - return describeFunctionComponentFrame(type.render, source, ownerFn); - - case REACT_MEMO_TYPE: - // Memo may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + if ((lanes & InputContinuousHydrationLane) !== NoLanes) { + return_highestLanePriority = InputContinuousHydrationLanePriority; + return InputContinuousHydrationLane; + } - case REACT_LAZY_TYPE: { - var lazyComponent = type; - var payload = lazyComponent._payload; - var init = lazyComponent._init; + var inputContinuousLanes = InputContinuousLanes & lanes; - try { - // Lazy may contain any component type so we recursively resolve it. - return describeUnknownElementTypeFrameInDEV( - init(payload), - source, - ownerFn - ); - } catch (x) {} - } - } + if (inputContinuousLanes !== NoLanes) { + return_highestLanePriority = InputContinuousLanePriority; + return inputContinuousLanes; } - return ""; -} + if ((lanes & DefaultHydrationLane) !== NoLanes) { + return_highestLanePriority = DefaultHydrationLanePriority; + return DefaultHydrationLane; + } -var loggedTypeFailures = {}; -var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var defaultLanes = DefaultLanes & lanes; -function setCurrentlyValidatingElement(element) { - { - if (element) { - var owner = element._owner; - var stack = describeUnknownElementTypeFrameInDEV( - element.type, - element._source, - owner ? owner.type : null - ); - ReactDebugCurrentFrame.setExtraStackFrame(stack); - } else { - ReactDebugCurrentFrame.setExtraStackFrame(null); - } + if (defaultLanes !== NoLanes) { + return_highestLanePriority = DefaultLanePriority; + return defaultLanes; } -} -function checkPropTypes(typeSpecs, values, location, componentName, element) { - { - // $FlowFixMe This is okay but Flow doesn't know it. - var has = Function.call.bind(Object.prototype.hasOwnProperty); + if ((lanes & TransitionHydrationLane) !== NoLanes) { + return_highestLanePriority = TransitionHydrationPriority; + return TransitionHydrationLane; + } - for (var typeSpecName in typeSpecs) { - if (has(typeSpecs, typeSpecName)) { - var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. + var transitionLanes = TransitionLanes & lanes; - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - if (typeof typeSpecs[typeSpecName] !== "function") { - var err = Error( - (componentName || "React class") + - ": " + - location + - " type `" + - typeSpecName + - "` is invalid; " + - "it must be a function, usually from the `prop-types` package, but received `" + - typeof typeSpecs[typeSpecName] + - "`." + - "This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`." - ); - err.name = "Invariant Violation"; - throw err; - } + if (transitionLanes !== NoLanes) { + return_highestLanePriority = TransitionPriority; + return transitionLanes; + } - error$1 = typeSpecs[typeSpecName]( - values, - typeSpecName, - componentName, - location, - null, - "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED" - ); - } catch (ex) { - error$1 = ex; - } + var retryLanes = RetryLanes & lanes; - if (error$1 && !(error$1 instanceof Error)) { - setCurrentlyValidatingElement(element); + if (retryLanes !== NoLanes) { + return_highestLanePriority = RetryLanePriority; + return retryLanes; + } - error( - "%s: type specification of %s" + - " `%s` is invalid; the type checker " + - "function must return `null` or an `Error` but returned a %s. " + - "You may have forgotten to pass an argument to the type checker " + - "creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and " + - "shape all require an argument).", - componentName || "React class", - location, - typeSpecName, - typeof error$1 - ); + if (lanes & SelectiveHydrationLane) { + return_highestLanePriority = SelectiveHydrationLanePriority; + return SelectiveHydrationLane; + } - setCurrentlyValidatingElement(null); - } + if ((lanes & IdleHydrationLane) !== NoLanes) { + return_highestLanePriority = IdleHydrationLanePriority; + return IdleHydrationLane; + } - if ( - error$1 instanceof Error && - !(error$1.message in loggedTypeFailures) - ) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error$1.message] = true; - setCurrentlyValidatingElement(element); + var idleLanes = IdleLanes & lanes; - error("Failed %s type: %s", location, error$1.message); + if (idleLanes !== NoLanes) { + return_highestLanePriority = IdleLanePriority; + return idleLanes; + } - setCurrentlyValidatingElement(null); - } - } - } + if ((OffscreenLane & lanes) !== NoLanes) { + return_highestLanePriority = OffscreenLanePriority; + return OffscreenLane; } -} -var valueStack = []; -var fiberStack; + { + error("Should have found matching lanes. This is a bug in React."); + } // This shouldn't be reachable, but as a fallback, return the entire bitmask. -{ - fiberStack = []; + return_highestLanePriority = DefaultLanePriority; + return lanes; } -var index = -1; +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case ImmediatePriority: + return SyncLanePriority; -function createCursor(defaultValue) { - return { - current: defaultValue - }; -} + case UserBlockingPriority: + return InputContinuousLanePriority; -function pop(cursor, fiber) { - if (index < 0) { - { - error("Unexpected pop."); - } + case NormalPriority: + case LowPriority: + // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration. + return DefaultLanePriority; - return; - } + case IdlePriority: + return IdleLanePriority; - { - if (fiber !== fiberStack[index]) { - error("Unexpected Fiber popped."); - } + default: + return NoLanePriority; } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case SyncLanePriority: + case SyncBatchedLanePriority: + return ImmediatePriority; - cursor.current = valueStack[index]; - valueStack[index] = null; + case InputDiscreteHydrationLanePriority: + case InputDiscreteLanePriority: + case InputContinuousHydrationLanePriority: + case InputContinuousLanePriority: + return UserBlockingPriority; - { - fiberStack[index] = null; - } + case DefaultHydrationLanePriority: + case DefaultLanePriority: + case TransitionHydrationPriority: + case TransitionPriority: + case SelectiveHydrationLanePriority: + case RetryLanePriority: + return NormalPriority; - index--; -} + case IdleHydrationLanePriority: + case IdleLanePriority: + case OffscreenLanePriority: + return IdlePriority; -function push(cursor, value, fiber) { - index++; - valueStack[index] = cursor.current; + case NoLanePriority: + return NoPriority; - { - fiberStack[index] = fiber; + default: { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); + } } - - cursor.current = value; } +function getNextLanes(root, wipLanes) { + // Early bailout if there's no pending work left. + var pendingLanes = root.pendingLanes; -var warnedAboutMissingGetChildContext; - -{ - warnedAboutMissingGetChildContext = {}; -} + if (pendingLanes === NoLanes) { + return_highestLanePriority = NoLanePriority; + return NoLanes; + } -var emptyContextObject = {}; + var nextLanes = NoLanes; + var nextLanePriority = NoLanePriority; + var expiredLanes = root.expiredLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; // Check if any work has expired. -{ - Object.freeze(emptyContextObject); -} // A cursor to the current merged context object on the stack. + if (expiredLanes !== NoLanes) { + nextLanes = expiredLanes; + nextLanePriority = return_highestLanePriority = SyncLanePriority; + } else { + // Do not work on any idle work until all the non-idle work has finished, + // even if the work is suspended. + var nonIdlePendingLanes = pendingLanes & NonIdleLanes; -var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed. + if (nonIdlePendingLanes !== NoLanes) { + var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes; -var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack. -// We use this to get access to the parent context after we have already -// pushed the next context provider, and now need to merge their contexts. + if (nonIdleUnblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes; -var previousContext = emptyContextObject; + if (nonIdlePingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(nonIdlePingedLanes); + nextLanePriority = return_highestLanePriority; + } + } + } else { + // The only remaining work is Idle. + var unblockedLanes = pendingLanes & ~suspendedLanes; -function getUnmaskedContext( - workInProgress, - Component, - didPushOwnContextIfProvider -) { - { - if (didPushOwnContextIfProvider && isContextProvider(Component)) { - // If the fiber is a context provider itself, when we read its context - // we may have already pushed its own child context on the stack. A context - // provider should not "see" its own child context. Therefore we read the - // previous (parent) context instead for a context provider. - return previousContext; + if (unblockedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(unblockedLanes); + nextLanePriority = return_highestLanePriority; + } else { + if (pingedLanes !== NoLanes) { + nextLanes = getHighestPriorityLanes(pingedLanes); + nextLanePriority = return_highestLanePriority; + } + } } - - return contextStackCursor.current; - } -} - -function cacheContext(workInProgress, unmaskedContext, maskedContext) { - { - var instance = workInProgress.stateNode; - instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext; - instance.__reactInternalMemoizedMaskedChildContext = maskedContext; } -} -function getMaskedContext(workInProgress, unmaskedContext) { - { - var type = workInProgress.type; - var contextTypes = type.contextTypes; + if (nextLanes === NoLanes) { + // This should only be reachable if we're suspended + // TODO: Consider warning in this path if a fallback timer is not scheduled. + return NoLanes; + } // If there are higher priority lanes, we'll include them even if they + // are suspended. - if (!contextTypes) { - return emptyContextObject; - } // Avoid recreating masked context unless unmasked context has changed. - // Failing to do this will result in unnecessary calls to componentWillReceiveProps. - // This may trigger infinite loops if componentWillReceiveProps calls setState. + nextLanes = pendingLanes & getEqualOrHigherPriorityLanes(nextLanes); // If we're already in the middle of a render, switching lanes will interrupt + // it and we'll lose our progress. We should only do this if the new lanes are + // higher priority. - var instance = workInProgress.stateNode; + if ( + wipLanes !== NoLanes && + wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't + // bother waiting until the root is complete. + (wipLanes & suspendedLanes) === NoLanes + ) { + getHighestPriorityLanes(wipLanes); + var wipLanePriority = return_highestLanePriority; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) { - return instance.__reactInternalMemoizedMaskedChildContext; + if (nextLanePriority <= wipLanePriority) { + return wipLanes; + } else { + return_highestLanePriority = nextLanePriority; } + } // Check for entangled lanes and add them to the batch. + // + // A lane is said to be entangled with another when it's not allowed to render + // in a batch that does not also include the other lane. Typically we do this + // when multiple updates have the same source, and we only want to respond to + // the most recent event from that source. + // + // Note that we apply entanglements *after* checking for partial work above. + // This means that if a lane is entangled during an interleaved event while + // it's already rendering, we won't interrupt it. This is intentional, since + // entanglement is usually "best effort": we'll try our best to render the + // lanes in the same batch, but it's not worth throwing out partially + // completed work in order to do it. + // + // For those exceptions where entanglement is semantically important, like + // useMutableSource, we should ensure that there is no partial work at the + // time we apply the entanglement. - var context = {}; - - for (var key in contextTypes) { - context[key] = unmaskedContext[key]; - } + var entangledLanes = root.entangledLanes; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(contextTypes, context, "context", name); - } // Cache unmasked context so we can avoid recreating masked context unless necessary. - // Context is created before the class component is instantiated so check for instance. + if (entangledLanes !== NoLanes) { + var entanglements = root.entanglements; + var lanes = nextLanes & entangledLanes; - if (instance) { - cacheContext(workInProgress, unmaskedContext, context); + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + nextLanes |= entanglements[index]; + lanes &= ~lane; } - - return context; } -} -function hasContextChanged() { - { - return didPerformWorkStackCursor.current; - } + return nextLanes; } +function getMostRecentEventTime(root, lanes) { + var eventTimes = root.eventTimes; + var mostRecentEventTime = NoTimestamp; -function isContextProvider(type) { - { - var childContextTypes = type.childContextTypes; - return childContextTypes !== null && childContextTypes !== undefined; - } -} + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var eventTime = eventTimes[index]; -function popContext(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); - } -} + if (eventTime > mostRecentEventTime) { + mostRecentEventTime = eventTime; + } -function popTopLevelContextObject(fiber) { - { - pop(didPerformWorkStackCursor, fiber); - pop(contextStackCursor, fiber); + lanes &= ~lane; } + + return mostRecentEventTime; } -function pushTopLevelContextObject(fiber, context, didChange) { - { - if (!(contextStackCursor.current === emptyContextObject)) { - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - } +function computeExpirationTime(lane, currentTime) { + // TODO: Expiration heuristic is constant per lane, so could use a map. + getHighestPriorityLanes(lane); + var priority = return_highestLanePriority; - push(contextStackCursor, context, fiber); - push(didPerformWorkStackCursor, didChange, fiber); + if (priority >= InputContinuousLanePriority) { + // User interactions should expire slightly more quickly. + // + // NOTE: This is set to the corresponding constant as in Scheduler.js. When + // we made it larger, a product metric in www regressed, suggesting there's + // a user interaction that's being starved by a series of synchronous + // updates. If that theory is correct, the proper solution is to fix the + // starvation. However, this scenario supports the idea that expiration + // times are an important safeguard when starvation does happen. + // + // Also note that, in the case of user input specifically, this will soon no + // longer be an issue because we plan to make user input synchronous by + // default (until you enter `startTransition`, of course.) + // + // If weren't planning to make these updates synchronous soon anyway, I + // would probably make this number a configurable parameter. + return currentTime + 250; + } else if (priority >= TransitionPriority) { + return currentTime + 5000; + } else { + // Anything idle priority or lower should never expire. + return NoTimestamp; } } -function processChildContext(fiber, type, parentContext) { - { - var instance = fiber.stateNode; - var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future. - // It has only been added in Fiber to match the (unintentional) behavior in Stack. +function markStarvedLanesAsExpired(root, currentTime) { + // TODO: This gets called every time we yield. We can optimize by storing + // the earliest expiration time on the root. Then use that to quickly bail out + // of this function. + var pendingLanes = root.pendingLanes; + var suspendedLanes = root.suspendedLanes; + var pingedLanes = root.pingedLanes; + var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their + // expiration time. If so, we'll assume the update is being starved and mark + // it as expired to force it to finish. - if (typeof instance.getChildContext !== "function") { - { - var componentName = getComponentName(type) || "Unknown"; + var lanes = pendingLanes; - if (!warnedAboutMissingGetChildContext[componentName]) { - warnedAboutMissingGetChildContext[componentName] = true; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + var expirationTime = expirationTimes[index]; - error( - "%s.childContextTypes is specified but there is no getChildContext() method " + - "on the instance. You can either define getChildContext() on %s or remove " + - "childContextTypes from it.", - componentName, - componentName - ); - } + if (expirationTime === NoTimestamp) { + // Found a pending lane with no expiration time. If it's not suspended, or + // if it's pinged, assume it's CPU-bound. Compute a new expiration time + // using the current time. + if ( + (lane & suspendedLanes) === NoLanes || + (lane & pingedLanes) !== NoLanes + ) { + // Assumes timestamps are monotonically increasing. + expirationTimes[index] = computeExpirationTime(lane, currentTime); } - - return parentContext; + } else if (expirationTime <= currentTime) { + // This lane expired + root.expiredLanes |= lane; } - var childContext = instance.getChildContext(); - - for (var contextKey in childContext) { - if (!(contextKey in childContextTypes)) { - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - } - } + lanes &= ~lane; + } +} // This returns the highest priority pending lanes regardless of whether they +function getLanesToRetrySynchronouslyOnError(root) { + var everythingButOffscreen = root.pendingLanes & ~OffscreenLane; - { - var name = getComponentName(type) || "Unknown"; - checkPropTypes(childContextTypes, childContext, "child context", name); - } + if (everythingButOffscreen !== NoLanes) { + return everythingButOffscreen; + } - return Object.assign({}, parentContext, childContext); + if (everythingButOffscreen & OffscreenLane) { + return OffscreenLane; } + + return NoLanes; +} +function returnNextLanesPriority() { + return return_highestLanePriority; +} +function includesNonIdleWork(lanes) { + return (lanes & NonIdleLanes) !== NoLanes; +} +function includesOnlyRetries(lanes) { + return (lanes & RetryLanes) === lanes; } +function includesOnlyTransitions(lanes) { + return (lanes & TransitionLanes) === lanes; +} // To ensure consistency across multiple updates in the same event, this should +// be a pure function, so that it always returns the same lane for given inputs. -function pushContextProvider(workInProgress) { - { - var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity. - // If the instance does not exist yet, we will push null at first, - // and replace it on the stack later when invalidating the context. +function findUpdateLane(lanePriority, wipLanes) { + switch (lanePriority) { + case NoLanePriority: + break; - var memoizedMergedChildContext = - (instance && instance.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; // Remember the parent context so we can merge with it later. - // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates. + case SyncLanePriority: + return SyncLane; - previousContext = contextStackCursor.current; - push(contextStackCursor, memoizedMergedChildContext, workInProgress); - push( - didPerformWorkStackCursor, - didPerformWorkStackCursor.current, - workInProgress - ); - return true; - } -} + case SyncBatchedLanePriority: + return SyncBatchedLane; -function invalidateContextProvider(workInProgress, type, didChange) { - { - var instance = workInProgress.stateNode; + case InputDiscreteLanePriority: { + var _lane = pickArbitraryLane(InputDiscreteLanes & ~wipLanes); - if (!instance) { - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); + if (_lane === NoLane) { + // Shift to the next priority level + return findUpdateLane(InputContinuousLanePriority, wipLanes); + } + + return _lane; } - if (didChange) { - // Merge parent and own context. - // Skip this if we're not updating due to sCU. - // This avoids unnecessarily recomputing memoized values. - var mergedContext = processChildContext( - workInProgress, - type, - previousContext - ); - instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one. - // It is important to unwind the context in the reverse order. + case InputContinuousLanePriority: { + var _lane2 = pickArbitraryLane(InputContinuousLanes & ~wipLanes); - pop(didPerformWorkStackCursor, workInProgress); - pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed. + if (_lane2 === NoLane) { + // Shift to the next priority level + return findUpdateLane(DefaultLanePriority, wipLanes); + } - push(contextStackCursor, mergedContext, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); - } else { - pop(didPerformWorkStackCursor, workInProgress); - push(didPerformWorkStackCursor, didChange, workInProgress); + return _lane2; } - } -} -function findCurrentUnmaskedContext(fiber) { - { - // Currently this is only used with renderSubtreeIntoContainer; not sure if it - // makes sense elsewhere - if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) { - throw Error( - "Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue." - ); - } + case DefaultLanePriority: { + var _lane3 = pickArbitraryLane(DefaultLanes & ~wipLanes); - var node = fiber; + if (_lane3 === NoLane) { + // If all the default lanes are already being worked on, look for a + // lane in the transition range. + _lane3 = pickArbitraryLane(TransitionLanes & ~wipLanes); - do { - switch (node.tag) { - case HostRoot: - return node.stateNode.context; + if (_lane3 === NoLane) { + // All the transition lanes are taken, too. This should be very + // rare, but as a last resort, pick a default lane. This will have + // the effect of interrupting the current work-in-progress render. + _lane3 = pickArbitraryLane(DefaultLanes); + } + } - case ClassComponent: { - var Component = node.type; + return _lane3; + } - if (isContextProvider(Component)) { - return node.stateNode.__reactInternalMemoizedMergedChildContext; - } + case TransitionPriority: // Should be handled by findTransitionLane instead - break; - } - } + case RetryLanePriority: + // Should be handled by findRetryLane instead + break; - node = node.return; - } while (node !== null); + case IdleLanePriority: + var lane = pickArbitraryLane(IdleLanes & ~wipLanes); - { - throw Error( - "Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue." - ); - } - } -} + if (lane === NoLane) { + lane = pickArbitraryLane(IdleLanes); + } -var LegacyRoot = 0; -var BlockingRoot = 1; -var ConcurrentRoot = 2; + return lane; + } -var rendererID = null; -var injectedHook = null; -var hasLoggedError = false; -var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined"; -function injectInternals(internals) { - if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === "undefined") { - // No DevTools - return false; + { + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); } +} // To ensure consistency across multiple updates in the same event, this should +// be pure function, so that it always returns the same lane for given inputs. - var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__; +function findTransitionLane(wipLanes, pendingLanes) { + // First look for lanes that are completely unclaimed, i.e. have no + // pending work. + var lane = pickArbitraryLane(TransitionLanes & ~pendingLanes); - if (hook.isDisabled) { - // This isn't a real property on the hook, but it can be set to opt out - // of DevTools integration and associated warnings and logs. - // https://github.com/facebook/react/issues/3877 - return true; + if (lane === NoLane) { + // If all lanes have pending work, look for a lane that isn't currently + // being worked on. + lane = pickArbitraryLane(TransitionLanes & ~wipLanes); + + if (lane === NoLane) { + // If everything is being worked on, pick any lane. This has the + // effect of interrupting the current work-in-progress. + lane = pickArbitraryLane(TransitionLanes); + } } - if (!hook.supportsFiber) { - { - error( - "The installed version of React DevTools is too old and will not work " + - "with the current version of React. Please update React DevTools. " + - "https://reactjs.org/link/react-devtools" - ); - } // DevTools exists, even though it doesn't support Fiber. + return lane; +} // To ensure consistency across multiple updates in the same event, this should +// be pure function, so that it always returns the same lane for given inputs. - return true; +function findRetryLane(wipLanes) { + // This is a fork of `findUpdateLane` designed specifically for Suspense + // "retries" — a special update that attempts to flip a Suspense boundary + // from its placeholder state to its primary/resolved state. + var lane = pickArbitraryLane(RetryLanes & ~wipLanes); + + if (lane === NoLane) { + lane = pickArbitraryLane(RetryLanes); } - try { - rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks. + return lane; +} - injectedHook = hook; - } catch (err) { - // Catch all errors because it is unsafe to throw during initialization. - { - error("React instrumentation encountered an error: %s.", err); - } - } // DevTools exists +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} - return true; +function getLowestPriorityLane(lanes) { + // This finds the most significant non-zero bit. + var index = 31 - clz32(lanes); + return index < 0 ? NoLanes : 1 << index; } -function onScheduleRoot(root, children) { - { - if ( - injectedHook && - typeof injectedHook.onScheduleFiberRoot === "function" - ) { - try { - injectedHook.onScheduleFiberRoot(rendererID, root, children); - } catch (err) { - if (!hasLoggedError) { - hasLoggedError = true; - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function getEqualOrHigherPriorityLanes(lanes) { + return (getLowestPriorityLane(lanes) << 1) - 1; } -function onCommitRoot(root, priorityLevel) { - if (injectedHook && typeof injectedHook.onCommitFiberRoot === "function") { - try { - var didError = (root.current.flags & DidCapture) === DidCapture; - if (enableProfilerTimer) { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - didError - ); - } else { - injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError); - } - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; +function pickArbitraryLane(lanes) { + // This wrapper function gets inlined. Only exists so to communicate that it + // doesn't matter which bit is selected; you can pick any bit without + // affecting the algorithms where its used. Here I'm using + // getHighestPriorityLane because it requires the fewest operations. + return getHighestPriorityLane(lanes); +} - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function pickArbitraryLaneIndex(lanes) { + return 31 - clz32(lanes); } -function onCommitUnmount(fiber) { - if (injectedHook && typeof injectedHook.onCommitFiberUnmount === "function") { - try { - injectedHook.onCommitFiberUnmount(rendererID, fiber); - } catch (err) { - { - if (!hasLoggedError) { - hasLoggedError = true; - error("React instrumentation encountered an error: %s", err); - } - } - } - } +function laneToIndex(lane) { + return pickArbitraryLaneIndex(lane); } -var NoFlags$1 = - /* */ - 0; // Represents whether effect should fire. +function includesSomeLane(a, b) { + return (a & b) !== NoLanes; +} +function isSubsetOfLanes(set, subset) { + return (set & subset) === subset; +} +function mergeLanes(a, b) { + return a | b; +} +function removeLanes(set, subset) { + return set & ~subset; +} // Seems redundant, but it changes the type from a single lane (used for +// updates) to a group of lanes (used for flushing work). -var HasEffect = - /* */ - 1; // Represents the phase in which the effect (not the clean-up) fires. +function laneToLanes(lane) { + return lane; +} +function createLaneMap(initial) { + // Intentionally pushing one by one. + // https://v8.dev/blog/elements-kinds#avoid-creating-holes + var laneMap = []; -var Layout = - /* */ - 2; -var Passive$1 = - /* */ - 4; + for (var i = 0; i < TotalLanes; i++) { + laneMap.push(initial); + } -// TODO: this is special because it gets imported during build. -// -// TODO: 17.0.2 has not been released to NPM; -// It exists as a placeholder so that DevTools can support work tag changes between releases. -// When we next publish a release (either 17.0.2 or 17.1.0), update the matching TODO in backend/renderer.js -var ReactVersion = "17.0.2"; + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; // TODO: Theoretically, any update to any lane can unblock any other lane. But + // it's not practical to try every single possible combination. We need a + // heuristic to decide which lanes to attempt to render, and in which batches. + // For now, we use the same heuristic as in the old ExpirationTimes model: + // retry any lane at equal or lower priority, but don't try updates at higher + // priority without also including the lower priority updates. This works well + // when considering updates across different priority levels, but isn't + // sufficient for updates within the same priority, since we want to treat + // those updates as parallel. + // Unsuspend any update at equal or lower priority. + + var higherPriorityLanes = updateLane - 1; // Turns 0b1000 into 0b0111 + + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + var eventTimes = root.eventTimes; + var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most + // recent event, and we assume time is monotonically increasing. -var NoMode = - /* */ - 0; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root tag instead + eventTimes[index] = eventTime; +} +function markRootSuspended(root, suspendedLanes) { + root.suspendedLanes |= suspendedLanes; + root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times. -var BlockingMode = - /* */ - 1; -var ConcurrentMode = - /* */ - 2; -var ProfileMode = - /* */ - 4; -var DebugTracingMode = - /* */ - 8; -var StrictLegacyMode = - /* */ - 16; + var expirationTimes = root.expirationTimes; + var lanes = suspendedLanes; -var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; -var NoTransition = 0; -function requestCurrentTransition() { - return ReactCurrentBatchConfig.transition; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; + } } - -/** - * inlined Object.is polyfill to avoid requiring consumers ship their own - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is - */ -function is(x, y) { - return ( - (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare - ); +function markRootPinged(root, pingedLanes, eventTime) { + root.pingedLanes |= root.suspendedLanes & pingedLanes; } +function hasDiscreteLanes(lanes) { + return (lanes & InputDiscreteLanes) !== NoLanes; +} +function markRootMutableRead(root, updateLane) { + root.mutableReadLanes |= updateLane & root.pendingLanes; +} +function markRootFinished(root, remainingLanes) { + var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; + root.pendingLanes = remainingLanes; // Let's try everything again -var objectIs = typeof Object.is === "function" ? Object.is : is; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes; + root.mutableReadLanes &= remainingLanes; + root.entangledLanes &= remainingLanes; + var entanglements = root.entanglements; + var eventTimes = root.eventTimes; + var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work -var hasOwnProperty = Object.prototype.hasOwnProperty; -/** - * Performs equality by iterating through keys on an object and returning false - * when any key has values which are not strictly equal between the arguments. - * Returns true when the values of all keys are strictly equal. - */ + var lanes = noLongerPendingLanes; -function shallowEqual(objA, objB) { - if (objectIs(objA, objB)) { - return true; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] = NoLanes; + eventTimes[index] = NoTimestamp; + expirationTimes[index] = NoTimestamp; + lanes &= ~lane; } +} +function markRootEntangled(root, entangledLanes) { + root.entangledLanes |= entangledLanes; + var entanglements = root.entanglements; + var lanes = entangledLanes; - if ( - typeof objA !== "object" || - objA === null || - typeof objB !== "object" || - objB === null - ) { - return false; + while (lanes > 0) { + var index = pickArbitraryLaneIndex(lanes); + var lane = 1 << index; + entanglements[index] |= entangledLanes; + lanes &= ~lane; } +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros. Only used on lanes, so assume input is an integer. +// Based on: +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 - var keysA = Object.keys(objA); - var keysB = Object.keys(objB); - - if (keysA.length !== keysB.length) { - return false; - } // Test for A's keys different from B. +var log = Math.log; +var LN2 = Math.LN2; - for (var i = 0; i < keysA.length; i++) { - if ( - !hasOwnProperty.call(objB, keysA[i]) || - !objectIs(objA[keysA[i]], objB[keysA[i]]) - ) { - return false; - } +function clz32Fallback(lanes) { + if (lanes === 0) { + return 32; } - return true; + return (31 - ((log(lanes) / LN2) | 0)) | 0; } -function describeFiber(fiber) { - var owner = fiber._debugOwner ? fiber._debugOwner.type : null; - var source = fiber._debugSource; - - switch (fiber.tag) { - case HostComponent: - return describeBuiltInComponentFrame(fiber.type, source, owner); - - case LazyComponent: - return describeBuiltInComponentFrame("Lazy", source, owner); +// Intentionally not named imports because Rollup would use dynamic dispatch for +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; - case SuspenseComponent: +{ + // Provide explicit error message when production+profiling bundle of e.g. + // react-dom is used with production (non-profiling) bundle of + // scheduler/tracing + if ( + !( + tracing.__interactionsRef != null && + tracing.__interactionsRef.current != null + ) + ) { + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); + } +} + +var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use +// ascending numbers so we can compare them like numbers. They start at 90 to +// avoid clashing with Scheduler's priorities. + +var ImmediatePriority$1 = 99; +var UserBlockingPriority$1 = 98; +var NormalPriority$1 = 97; +var LowPriority$1 = 96; +var IdlePriority$1 = 95; // NoPriority is the absence of priority. Also React-only. + +var NoPriority$1 = 90; +var shouldYield = Scheduler_shouldYield; +var requestPaint = // Fall back gracefully if we're running an older version of Scheduler. + Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function() {}; +var syncQueue = null; +var immediateQueueCallbackNode = null; +var isFlushingSyncQueue = false; +var initialTimeMs$1 = Scheduler_now$1(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly. +// This will be the case for modern browsers that support `performance.now`. In +// older browsers, Scheduler falls back to `Date.now`, which returns a Unix +// timestamp. In that case, subtract the module initialization time to simulate +// the behavior of performance.now and keep our times small enough to fit +// within 32 bits. +// TODO: Consider lifting this into Scheduler. + +var now = + initialTimeMs$1 < 10000 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return ImmediatePriority$1; + + case Scheduler_UserBlockingPriority: + return UserBlockingPriority$1; + + case Scheduler_NormalPriority: + return NormalPriority$1; + + case Scheduler_LowPriority: + return LowPriority$1; + + case Scheduler_IdlePriority: + return IdlePriority$1; + + default: { + throw Error("Unknown priority level."); + } + } +} + +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case ImmediatePriority$1: + return Scheduler_ImmediatePriority; + + case UserBlockingPriority$1: + return Scheduler_UserBlockingPriority; + + case NormalPriority$1: + return Scheduler_NormalPriority; + + case LowPriority$1: + return Scheduler_LowPriority; + + case IdlePriority$1: + return Scheduler_IdlePriority; + + default: { + throw Error("Unknown priority level."); + } + } +} + +function runWithPriority(reactPriorityLevel, fn) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(priorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(priorityLevel, callback, options); +} +function scheduleSyncCallback(callback) { + // Push this callback into an internal queue. We'll flush these either in + // the next tick, or earlier if something calls `flushSyncCallbackQueue`. + if (syncQueue === null) { + syncQueue = [callback]; // Flush the queue in the next tick, at the earliest. + + immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ); + } else { + // Push onto existing queue. Don't need to schedule a callback because + // we already scheduled one when we created the queue. + syncQueue.push(callback); + } + + return fakeCallbackNode; +} +function cancelCallback(callbackNode) { + if (callbackNode !== fakeCallbackNode) { + Scheduler_cancelCallback(callbackNode); + } +} +function flushSyncCallbackQueue() { + if (immediateQueueCallbackNode !== null) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + + flushSyncCallbackQueueImpl(); +} + +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && syncQueue !== null) { + // Prevent re-entrancy. + isFlushingSyncQueue = true; + var i = 0; + + { + try { + var _isSync2 = true; + var _queue = syncQueue; + runWithPriority(ImmediatePriority$1, function() { + for (; i < _queue.length; i++) { + var callback = _queue[i]; + + do { + callback = callback(_isSync2); + } while (callback !== null); + } + }); + syncQueue = null; + } catch (error) { + // If something throws, leave the remaining callbacks on the queue. + if (syncQueue !== null) { + syncQueue = syncQueue.slice(i + 1); + } // Resume flushing in the next tick + + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ); + throw error; + } finally { + isFlushingSyncQueue = false; + } + } + } +} + +// TODO: this is special because it gets imported during build. +var ReactVersion = "17.0.1-454c2211c"; + +var NoMode = 0; +var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root +// tag instead + +var BlockingMode = 2; +var ConcurrentMode = 4; +var ProfileMode = 8; +var DebugTracingMode = 16; + +var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; +var NoTransition = 0; +function requestCurrentTransition() { + return ReactCurrentBatchConfig.transition; +} + +/** + * inlined Object.is polyfill to avoid requiring consumers ship their own + * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is + */ +function is(x, y) { + return ( + (x === y && (x !== 0 || 1 / x === 1 / y)) || (x !== x && y !== y) // eslint-disable-line no-self-compare + ); +} + +var objectIs = typeof Object.is === "function" ? Object.is : is; + +var hasOwnProperty = Object.prototype.hasOwnProperty; +/** + * Performs equality by iterating through keys on an object and returning false + * when any key has values which are not strictly equal between the arguments. + * Returns true when the values of all keys are strictly equal. + */ + +function shallowEqual(objA, objB) { + if (objectIs(objA, objB)) { + return true; + } + + if ( + typeof objA !== "object" || + objA === null || + typeof objB !== "object" || + objB === null + ) { + return false; + } + + var keysA = Object.keys(objA); + var keysB = Object.keys(objB); + + if (keysA.length !== keysB.length) { + return false; + } // Test for A's keys different from B. + + for (var i = 0; i < keysA.length; i++) { + if ( + !hasOwnProperty.call(objB, keysA[i]) || + !objectIs(objA[keysA[i]], objB[keysA[i]]) + ) { + return false; + } + } + + return true; +} + +function describeFiber(fiber) { + var owner = fiber._debugOwner ? fiber._debugOwner.type : null; + var source = fiber._debugSource; + + switch (fiber.tag) { + case HostComponent: + return describeBuiltInComponentFrame(fiber.type, source, owner); + + case LazyComponent: + return describeBuiltInComponentFrame("Lazy", source, owner); + + case SuspenseComponent: return describeBuiltInComponentFrame("Suspense", source, owner); case SuspenseListComponent: @@ -6279,7 +6205,7 @@ var ReactStrictModeWarnings = { var node = fiber; while (node !== null) { - if (node.mode & StrictLegacyMode) { + if (node.mode & StrictMode) { maybeStrictRoot = node; } @@ -6310,7 +6236,7 @@ var ReactStrictModeWarnings = { fiber, instance ) { - // Dedupe strategy: Warn once per component. + // Dedup strategy: Warn once per component. if (didWarnAboutUnsafeLifecycles.has(fiber.type)) { return; } @@ -6323,7 +6249,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictLegacyMode && + fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === "function" ) { pendingUNSAFE_ComponentWillMountWarnings.push(fiber); @@ -6337,7 +6263,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictLegacyMode && + fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === "function" ) { pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber); @@ -6351,7 +6277,7 @@ var ReactStrictModeWarnings = { } if ( - fiber.mode & StrictLegacyMode && + fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === "function" ) { pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber); @@ -6669,7 +6595,9 @@ function exitDisallowedContextReadInDEV() { isDisallowedContextReadInDEV = false; } } -function pushProvider(providerFiber, context, nextValue) { +function pushProvider(providerFiber, nextValue) { + var context = providerFiber.type._context; + { push(valueCursor, context._currentValue, providerFiber); context._currentValue = nextValue; @@ -6690,9 +6618,10 @@ function pushProvider(providerFiber, context, nextValue) { } } } -function popProvider(context, providerFiber) { +function popProvider(providerFiber) { var currentValue = valueCursor.current; pop(valueCursor, providerFiber); + var context = providerFiber.type._context; { context._currentValue = currentValue; @@ -6779,31 +6708,16 @@ function propagateContextChange( // Match! Schedule an update on this fiber. if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. - var lane = pickArbitraryLane(renderLanes); - var update = createUpdate(NoTimestamp, lane); + var update = createUpdate( + NoTimestamp, + pickArbitraryLane(renderLanes) + ); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if // this render is thrown away. Since it's a race condition, not sure it's // worth fixing. - // Inlined `enqueueUpdate` to remove interleaved update check - - var updateQueue = fiber.updateQueue; - - if (updateQueue === null); - else { - var sharedQueue = updateQueue.shared; - var pending = sharedQueue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - sharedQueue.pending = update; - } + enqueueUpdate(fiber, update); } fiber.lanes = mergeLanes(fiber.lanes, renderLanes); @@ -6938,48 +6852,6 @@ function readContext(context, observedBits) { return context._currentValue; } -// An array of all update queues that received updates during the current -// render. When this render exits, either because it finishes or because it is -// interrupted, the interleaved updates will be transfered onto the main part -// of the queue. -var interleavedQueues = null; -function pushInterleavedQueue(queue) { - if (interleavedQueues === null) { - interleavedQueues = [queue]; - } else { - interleavedQueues.push(queue); - } -} -function enqueueInterleavedUpdates() { - // Transfer the interleaved updates onto the main queue. Each queue has a - // `pending` field and an `interleaved` field. When they are not null, they - // point to the last node in a circular linked list. We need to append the - // interleaved list to the end of the pending list by joining them into a - // single, circular list. - if (interleavedQueues !== null) { - for (var i = 0; i < interleavedQueues.length; i++) { - var queue = interleavedQueues[i]; - var lastInterleavedUpdate = queue.interleaved; - - if (lastInterleavedUpdate !== null) { - queue.interleaved = null; - var firstInterleavedUpdate = lastInterleavedUpdate.next; - var lastPendingUpdate = queue.pending; - - if (lastPendingUpdate !== null) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = firstInterleavedUpdate; - lastInterleavedUpdate.next = firstPendingUpdate; - } - - queue.pending = lastInterleavedUpdate; - } - } - - interleavedQueues = null; - } -} - var UpdateState = 0; var ReplaceState = 1; var ForceUpdate = 2; @@ -7002,9 +6874,7 @@ function initializeUpdateQueue(fiber) { firstBaseUpdate: null, lastBaseUpdate: null, shared: { - pending: null, - interleaved: null, - lanes: NoLanes + pending: null }, effects: null }; @@ -7037,7 +6907,7 @@ function createUpdate(eventTime, lane) { }; return update; } -function enqueueUpdate(fiber, update, lane) { +function enqueueUpdate(fiber, update) { var updateQueue = fiber.updateQueue; if (updateQueue === null) { @@ -7046,36 +6916,18 @@ function enqueueUpdate(fiber, update, lane) { } var sharedQueue = updateQueue.shared; + var pending = sharedQueue.pending; - if (isInterleavedUpdate(fiber)) { - var interleaved = sharedQueue.interleaved; - - if (interleaved === null) { - // This is the first update. Create a circular list. - update.next = update; // At the end of the current render, this queue's interleaved updates will - // be transfered to the pending queue. - - pushInterleavedQueue(sharedQueue); - } else { - update.next = interleaved.next; - interleaved.next = update; - } - - sharedQueue.interleaved = update; + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; } else { - var pending = sharedQueue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - sharedQueue.pending = update; + update.next = pending.next; + pending.next = update; } + sharedQueue.pending = update; + { if ( currentlyProcessingQueue === sharedQueue && @@ -7092,38 +6944,11 @@ function enqueueUpdate(fiber, update, lane) { } } } -function entangleTransitions(root, fiber, lane) { - var updateQueue = fiber.updateQueue; - - if (updateQueue === null) { - // Only occurs if the fiber has been unmounted. - return; - } - - var sharedQueue = updateQueue.shared; - - if (isTransitionLane(lane)) { - var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must - // have finished. We can remove them from the shared queue, which represents - // a superset of the actually pending lanes. In some cases we may entangle - // more than we need to, but that's OK. In fact it's worse if we *don't* - // entangle when we should. - - queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. - - var newQueueLanes = mergeLanes(queueLanes, lane); - sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if - // the lane finished since the last time we entangled it. So we need to - // entangle it again, just to be sure. - - markRootEntangled(root, newQueueLanes); - } -} -function enqueueCapturedUpdate(workInProgress, capturedUpdate) { - // Captured updates are updates that are thrown by a child during the render - // phase. They should be discarded if the render is aborted. Therefore, - // we should only put them on the work-in-progress queue, not the current one. - var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. +function enqueueCapturedUpdate(workInProgress, capturedUpdate) { + // Captured updates are updates that are thrown by a child during the render + // phase. They should be discarded if the render is aborted. Therefore, + // we should only put them on the work-in-progress queue, not the current one. + var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone. var current = workInProgress.alternate; @@ -7220,7 +7045,7 @@ function getStateFromUpdate( var nextState = payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -7258,7 +7083,7 @@ function getStateFromUpdate( partialState = _payload.call(instance, prevState, nextProps); { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -7448,24 +7273,7 @@ function processUpdateQueue(workInProgress, props, instance, renderLanes) { queue.baseState = newBaseState; queue.firstBaseUpdate = newFirstBaseUpdate; - queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to - // process them during this render, but we do need to track which lanes - // are remaining. - - var lastInterleaved = queue.shared.interleaved; - - if (lastInterleaved !== null) { - var interleaved = lastInterleaved; - - do { - newLanes = mergeLanes(newLanes, interleaved.lane); - interleaved = interleaved.next; - } while (interleaved !== lastInterleaved); - } else if (firstBaseUpdate === null) { - // `queue.lanes` is used for entangling transitions. We can set it back to - // zero once the queue is empty. - queue.shared.lanes = NoLanes; - } // Set the remaining expiration time to be whatever is remaining in the queue. + queue.lastBaseUpdate = newLastBaseUpdate; // Set the remaining expiration time to be whatever is remaining in the queue. // This should be fine because the only two other things that contribute to // expiration time are props and context. We're already in the middle of the // begin phase by the time we start processing the queue, so we've already @@ -7606,7 +7414,7 @@ function applyDerivedStateFromProps( var prevState = workInProgress.memoizedState; { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -7655,11 +7463,7 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); - - if (root !== null) { - entangleTransitions(root, fiber, lane); - } + scheduleUpdateOnFiber(fiber, lane, eventTime); }, enqueueReplaceState: function(inst, payload, callback) { var fiber = get(inst); @@ -7678,11 +7482,7 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); - - if (root !== null) { - entangleTransitions(root, fiber, lane); - } + scheduleUpdateOnFiber(fiber, lane, eventTime); }, enqueueForceUpdate: function(inst, callback) { var fiber = get(inst); @@ -7700,11 +7500,7 @@ var classComponentUpdater = { } enqueueUpdate(fiber, update); - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); - - if (root !== null) { - entangleTransitions(root, fiber, lane); - } + scheduleUpdateOnFiber(fiber, lane, eventTime); } }; @@ -7721,7 +7517,7 @@ function checkShouldComponentUpdate( if (typeof instance.shouldComponentUpdate === "function") { { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -8057,7 +7853,7 @@ function constructClassInstance(workInProgress, ctor, props) { } // Instantiate twice to help detect side-effects. { - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { @@ -8270,7 +8066,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } } - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { ReactStrictModeWarnings.recordLegacyContextWarning( workInProgress, instance @@ -8314,9 +8110,7 @@ function mountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } } @@ -8378,9 +8172,7 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } return false; @@ -8426,17 +8218,13 @@ function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) { } if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } } else { // If an update was already in progress, we should schedule an Update // effect even though we're bailing out, so that cWU/cDU are called. if (typeof instance.componentDidMount === "function") { - { - workInProgress.flags |= Update; - } + workInProgress.flags |= Update; } // If shouldComponentUpdate returned false, we should still update the // memoized state to indicate that this work can be reused. @@ -8686,7 +8474,7 @@ function coerceRef(returnFiber, current, element) { // TODO: Clean this up once we turn on the string ref warning for // everyone, because the strict mode case will no longer be relevant if ( - (returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs + (returnFiber.mode & StrictMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs // because these cannot be automatically converted to an arrow function // using a codemod. Therefore, we don't have to warn about string refs again. !( @@ -8788,14 +8576,12 @@ function coerceRef(returnFiber, current, element) { function throwOnInvalidObjectType(returnFiber, newChild) { if (returnFiber.type !== "textarea") { - var childString = Object.prototype.toString.call(newChild); - { throw Error( "Objects are not valid as a React child (found: " + - (childString === "[object Object]" + (Object.prototype.toString.call(newChild) === "[object Object]" ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : childString) + + : newChild) + "). If you meant to render a collection of children, use an array instead." ); } @@ -8818,7 +8604,7 @@ function warnOnFunctionType(returnFiber) { "Or maybe you meant to call this function rather than return it." ); } -} +} // This wrapper function exists because I expect to clone the code in each path // to be able to optimize each path individually by branching early. This needs // a compiler or we can do it manually. Helpers that don't need this branching // live outside of this function. @@ -8828,16 +8614,23 @@ function ChildReconciler(shouldTrackSideEffects) { if (!shouldTrackSideEffects) { // Noop. return; - } + } // Deletions are added in reversed order so we add it to the front. + // At this point, the return fiber's effect list is empty except for + // deletions, so we can just append the deletion to the list. The remaining + // effects aren't added until the complete phase. Once we implement + // resuming, this may not be true. - var deletions = returnFiber.deletions; + var last = returnFiber.lastEffect; - if (deletions === null) { - returnFiber.deletions = [childToDelete]; - returnFiber.flags |= ChildDeletion; + if (last !== null) { + last.nextEffect = childToDelete; + returnFiber.lastEffect = childToDelete; } else { - deletions.push(childToDelete); + returnFiber.firstEffect = returnFiber.lastEffect = childToDelete; } + + childToDelete.nextEffect = null; + childToDelete.flags = Deletion; } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -8901,7 +8694,7 @@ function ChildReconciler(shouldTrackSideEffects) { if (oldIndex < lastPlacedIndex) { // This is a move. - newFiber.flags |= Placement; + newFiber.flags = Placement; return lastPlacedIndex; } else { // This item can stay in place. @@ -8909,7 +8702,7 @@ function ChildReconciler(shouldTrackSideEffects) { } } else { // This is an insertion. - newFiber.flags |= Placement; + newFiber.flags = Placement; return lastPlacedIndex; } } @@ -8918,7 +8711,7 @@ function ChildReconciler(shouldTrackSideEffects) { // This is simpler for the single child case. We only need to do a // placement for inserting new children. if (shouldTrackSideEffects && newFiber.alternate === null) { - newFiber.flags |= Placement; + newFiber.flags = Placement; } return newFiber; @@ -8939,26 +8732,10 @@ function ChildReconciler(shouldTrackSideEffects) { } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - - if (elementType === REACT_FRAGMENT_TYPE) { - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - } - if (current !== null) { if ( - current.elementType === elementType || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(current, element) || // Lazy types should reconcile their resolved type. - // We need to do this after the Hot Reloading check above, - // because hot reloading has different semantics than prod because - // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements + current.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(current, element) ) { // Move based on index var existing = useFiber(current, element.props); @@ -9097,6 +8874,16 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: { if (newChild.key === key) { + if (newChild.type === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ); + } + return updateElement(returnFiber, oldFiber, newChild, lanes); } else { return null; @@ -9154,6 +8941,16 @@ function ChildReconciler(shouldTrackSideEffects) { newChild.key === null ? newIdx : newChild.key ) || null; + if (newChild.type === REACT_FRAGMENT_TYPE) { + return updateFragment( + returnFiber, + _matchedFiber, + newChild.props.children, + lanes, + newChild.key + ); + } + return updateElement(returnFiber, _matchedFiber, newChild, lanes); } @@ -9647,43 +9444,45 @@ function ChildReconciler(shouldTrackSideEffects) { // TODO: If key === null and child.key === null, then this only applies to // the first item in the list. if (child.key === key) { - var elementType = element.type; + switch (child.tag) { + case Fragment: { + if (element.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren(returnFiber, child.sibling); + var existing = useFiber(child, element.props.children); + existing.return = returnFiber; - if (elementType === REACT_FRAGMENT_TYPE) { - if (child.tag === Fragment) { - deleteRemainingChildren(returnFiber, child.sibling); - var existing = useFiber(child, element.props.children); - existing.return = returnFiber; + { + existing._debugSource = element._source; + existing._debugOwner = element._owner; + } - { - existing._debugSource = element._source; - existing._debugOwner = element._owner; + return existing; } - return existing; + break; } - } else { - if ( - child.elementType === elementType || // Keep this check inline so it only runs on the false path: - isCompatibleFamilyForHotReloading(child, element) || // Lazy types should reconcile their resolved type. - // We need to do this after the Hot Reloading check above, - // because hot reloading has different semantics than prod because - // it doesn't resuspend. So we can't let the call below suspend. - enableLazyElements - ) { - deleteRemainingChildren(returnFiber, child.sibling); - var _existing = useFiber(child, element.props); + default: { + if ( + child.elementType === element.type || // Keep this check inline so it only runs on the false path: + isCompatibleFamilyForHotReloading(child, element) + ) { + deleteRemainingChildren(returnFiber, child.sibling); + + var _existing = useFiber(child, element.props); - _existing.ref = coerceRef(returnFiber, child, element); - _existing.return = returnFiber; + _existing.ref = coerceRef(returnFiber, child, element); + _existing.return = returnFiber; - { - _existing._debugSource = element._source; - _existing._debugOwner = element._owner; + { + _existing._debugSource = element._source; + _existing._debugOwner = element._owner; + } + + return _existing; } - return _existing; + break; } } // Didn't match. @@ -10114,6 +9913,21 @@ function findFirstSuspended(row) { return null; } +var NoFlags$1 = + /* */ + 0; // Represents whether effect should fire. + +var HasEffect = + /* */ + 1; // Represents the phase in which the effect (not the clean-up) fires. + +var Layout = + /* */ + 2; +var Passive$1 = + /* */ + 4; + var isHydrating = false; function enterHydrationState(fiber) { @@ -10209,12 +10023,6 @@ function warnAboutMultipleRenderersDEV(mutableSource) { } } // Eager reads the version of a mutable source and stores it on the root. -function getSuspendedCachePool() { - { - return null; - } // We check the cache on the stack first, since that's the one any new Caches -} - var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig; var didWarnAboutMismatchedHooksForComponent; @@ -10500,20 +10308,7 @@ function renderWithHooks( { currentHookNameInDev = null; hookTypesDev = null; - hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last - // render. If this fires, it suggests that we incorrectly reset the static - // flags in some other part of the codebase. This has happened before, for - // example, in the SuspenseList implementation. - - if ( - current !== null && - (current.flags & PassiveStatic) !== (workInProgress.flags & PassiveStatic) - ) { - error( - "Internal React error: Expected static flag was missing. Please " + - "notify the React team." - ); - } + hookTypesUpdateIndexDev = -1; } didScheduleRenderPhaseUpdate = false; @@ -10527,13 +10322,8 @@ function renderWithHooks( return children; } function bailoutHooks(current, workInProgress, lanes) { - workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the - // complete phase (bubbleProperties). - - { - workInProgress.flags &= ~(Passive | Update); - } - + workInProgress.updateQueue = current.updateQueue; + workInProgress.flags &= ~(Passive | Update); current.lanes = removeLanes(current.lanes, lanes); } function resetHooksAfterThrow() { @@ -10684,8 +10474,6 @@ function mountReducer(reducer, initialArg, init) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialState @@ -10823,28 +10611,6 @@ function updateReducer(reducer, initialArg, init) { hook.baseState = newBaseState; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = newState; - } // Interleaved updates are stored on a separate queue. We aren't going to - // process them during this render, but we do need to track which lanes - // are remaining. - - var lastInterleaved = queue.interleaved; - - if (lastInterleaved !== null) { - var interleaved = lastInterleaved; - - do { - var interleavedLane = interleaved.lane; - currentlyRenderingFiber$1.lanes = mergeLanes( - currentlyRenderingFiber$1.lanes, - interleavedLane - ); - markSkippedUpdateLanes(interleavedLane); - interleaved = interleaved.next; - } while (interleaved !== lastInterleaved); - } else if (baseQueue === null) { - // `queue.lanes` is used for entangling transitions. We can set it back to - // zero once the queue is empty. - queue.lanes = NoLanes; } var dispatch = queue.dispatch; @@ -10972,48 +10738,11 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { // // This can lead to tearing in the first renderer when it resumes, // but there's nothing we can do about that (short of throwing here and refusing to continue the render). - markSourceAsDirty(source); // Intentioally throw an error to force React to retry synchronously. During - // the synchronous retry, it will block interleaved mutations, so we should - // get a consistent read. Therefore, the following error should never be - // visible to the user. - // - // If it were to become visible to the user, it suggests one of two things: - // a bug in React, or (more likely), a mutation during the render phase that - // caused the second re-render attempt to be different from the first. - // - // We know it's the second case if the logs are currently disabled. So in - // dev, we can present a more accurate error message. - - { - // eslint-disable-next-line react-internal/no-production-logging - if (console.log.__reactDisabledLog) { - // If the logs are disabled, this is the dev-only double render. This is - // only reachable if there was a mutation during render. Show a helpful - // error message. - // - // Something interesting to note: because we only double render in - // development, this error will never happen during production. This is - // actually true of all errors that occur during a double render, - // because if the first render had thrown, we would have exited the - // begin phase without double rendering. We should consider suppressing - // any error from a double render (with a warning) to more closely match - // the production behavior. - var componentName = getComponentName(currentlyRenderingFiber$1.type); - - { - throw Error( - "A mutable source was mutated while the " + - componentName + - " component was rendering. This is not supported. Move any mutations into event handlers or effects." - ); - } - } - } // We expect this error not to be thrown during the synchronous retry, - // because we blocked interleaved mutations. + markSourceAsDirty(source); { throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } } @@ -11149,8 +10878,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { // including any interleaving updates that occur. var newQueue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -11198,8 +10925,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; var queue = (hook.queue = { pending: null, - interleaved: null, - lanes: NoLanes, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -11293,7 +11018,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevDeps = prevEffect.deps; if (areHookInputsEqual(nextDeps, prevDeps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps); + pushEffect(hookFlags, create, destroy, nextDeps); return; } } @@ -11316,9 +11041,7 @@ function mountEffect(create, deps) { } } - { - return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps); - } + return mountEffectImpl(Update | Passive, Passive$1, create, deps); } function updateEffect(create, deps) { @@ -11329,13 +11052,11 @@ function updateEffect(create, deps) { } } - return updateEffectImpl(Passive, Passive$1, create, deps); + return updateEffectImpl(Update | Passive, Passive$1, create, deps); } function mountLayoutEffect(create, deps) { - { - return mountEffectImpl(Update, Layout, create, deps); - } + return mountEffectImpl(Update, Layout, create, deps); } function updateLayoutEffect(create, deps) { @@ -11387,15 +11108,12 @@ function mountImperativeHandle(ref, create, deps) { var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null; - - { - return mountEffectImpl( - Update, - Layout, - imperativeHandleEffect.bind(null, create, ref), - effectDeps - ); - } + return mountEffectImpl( + Update, + Layout, + imperativeHandleEffect.bind(null, create, ref), + effectDeps + ); } function updateImperativeHandle(ref, create, deps) { @@ -11550,15 +11268,15 @@ function startTransition(setPending, callback) { { runWithPriority( - priorityLevel < UserBlockingPriority - ? UserBlockingPriority + priorityLevel < UserBlockingPriority$1 + ? UserBlockingPriority$1 : priorityLevel, function() { setPending(true); } ); runWithPriority( - priorityLevel > NormalPriority ? NormalPriority : priorityLevel, + priorityLevel > NormalPriority$1 ? NormalPriority$1 : priorityLevel, function() { var prevTransition = ReactCurrentBatchConfig$1.transition; ReactCurrentBatchConfig$1.transition = 1; @@ -11670,7 +11388,19 @@ function dispatchAction(fiber, queue, action) { eagerReducer: null, eagerState: null, next: null - }; + }; // Append the update to the end of the list. + + var pending = queue.pending; + + if (pending === null) { + // This is the first update. Create a circular list. + update.next = update; + } else { + update.next = pending.next; + pending.next = update; + } + + queue.pending = update; var alternate = fiber.alternate; if ( @@ -11681,47 +11411,7 @@ function dispatchAction(fiber, queue, action) { // queue -> linked list of updates. After this render pass, we'll restart // and apply the stashed updates on top of the work-in-progress hook. didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true; - var pending = queue.pending; - - if (pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = pending.next; - pending.next = update; - } - - queue.pending = update; } else { - if (isInterleavedUpdate(fiber)) { - var interleaved = queue.interleaved; - - if (interleaved === null) { - // This is the first update. Create a circular list. - update.next = update; // At the end of the current render, this queue's interleaved updates will - // be transfered to the pending queue. - - pushInterleavedQueue(queue); - } else { - update.next = interleaved.next; - interleaved.next = update; - } - - queue.interleaved = update; - } else { - var _pending = queue.pending; - - if (_pending === null) { - // This is the first update. Create a circular list. - update.next = update; - } else { - update.next = _pending.next; - _pending.next = update; - } - - queue.pending = update; - } - if ( fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes) @@ -11774,24 +11464,7 @@ function dispatchAction(fiber, queue, action) { } } - var root = scheduleUpdateOnFiber(fiber, lane, eventTime); - - if (isTransitionLane(lane) && root !== null) { - var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they - // must have finished. We can remove them from the shared queue, which - // represents a superset of the actually pending lanes. In some cases we - // may entangle more than we need to, but that's OK. In fact it's worse if - // we *don't* entangle when we should. - - queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes. - - var newQueueLanes = mergeLanes(queueLanes, lane); - queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if - // the lane finished since the last time we entangled it. So we need to - // entangle it again, just to be sure. - - markRootEntangled(root, newQueueLanes); - } + scheduleUpdateOnFiber(fiber, lane, eventTime); } } @@ -11813,7 +11486,6 @@ var ContextOnlyDispatcher = { useOpaqueIdentifier: throwInvalidHookError, unstable_isNewReconciler: enableNewReconciler }; - var HooksDispatcherOnMountInDEV = null; var HooksDispatcherOnMountWithHookTypesInDEV = null; var HooksDispatcherOnUpdateInDEV = null; @@ -11943,7 +11615,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnMountWithHookTypesInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -12041,7 +11712,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -12139,7 +11809,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - HooksDispatcherOnRerenderInDEV = { readContext: function(context, observedBits) { return readContext(context, observedBits); @@ -12237,7 +11906,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - InvalidNestedHooksDispatcherOnMountInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12350,7 +12018,6 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; }, unstable_isNewReconciler: enableNewReconciler }; - InvalidNestedHooksDispatcherOnUpdateInDEV = { readContext: function(context, observedBits) { warnInvalidContextAccess(); @@ -12423,704 +12090,300 @@ var InvalidNestedHooksDispatcherOnRerenderInDEV = null; warnInvalidHookAccess(); updateHookTypesDev(); var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; - - InvalidNestedHooksDispatcherOnRerenderInDEV = { - readContext: function(context, observedBits) { - warnInvalidContextAccess(); - return readContext(context, observedBits); - }, - useCallback: function(callback, deps) { - currentHookNameInDev = "useCallback"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateCallback(callback, deps); - }, - useContext: function(context, observedBits) { - currentHookNameInDev = "useContext"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return readContext(context, observedBits); - }, - useEffect: function(create, deps) { - currentHookNameInDev = "useEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateEffect(create, deps); - }, - useImperativeHandle: function(ref, create, deps) { - currentHookNameInDev = "useImperativeHandle"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateImperativeHandle(ref, create, deps); - }, - useLayoutEffect: function(create, deps) { - currentHookNameInDev = "useLayoutEffect"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateLayoutEffect(create, deps); - }, - useMemo: function(create, deps) { - currentHookNameInDev = "useMemo"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return updateMemo(create, deps); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useReducer: function(reducer, initialArg, init) { - currentHookNameInDev = "useReducer"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderReducer(reducer, initialArg, init); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useRef: function(initialValue) { - currentHookNameInDev = "useRef"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateRef(); - }, - useState: function(initialState) { - currentHookNameInDev = "useState"; - warnInvalidHookAccess(); - updateHookTypesDev(); - var prevDispatcher = ReactCurrentDispatcher$1.current; - ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - - try { - return rerenderState(initialState); - } finally { - ReactCurrentDispatcher$1.current = prevDispatcher; - } - }, - useDebugValue: function(value, formatterFn) { - currentHookNameInDev = "useDebugValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateDebugValue(); - }, - useDeferredValue: function(value) { - currentHookNameInDev = "useDeferredValue"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderDeferredValue(value); - }, - useTransition: function() { - currentHookNameInDev = "useTransition"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderTransition(); - }, - useMutableSource: function(source, getSnapshot, subscribe) { - currentHookNameInDev = "useMutableSource"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return updateMutableSource(source, getSnapshot, subscribe); - }, - useOpaqueIdentifier: function() { - currentHookNameInDev = "useOpaqueIdentifier"; - warnInvalidHookAccess(); - updateHookTypesDev(); - return rerenderOpaqueIdentifier(); - }, - unstable_isNewReconciler: enableNewReconciler - }; -} - -var now$1 = Scheduler.unstable_now; -var commitTime = 0; -var profilerStartTime = -1; - -function getCommitTime() { - return commitTime; -} - -function recordCommitTime() { - commitTime = now$1(); -} - -function startProfilerTimer(fiber) { - profilerStartTime = now$1(); - - if (fiber.actualStartTime < 0) { - fiber.actualStartTime = now$1(); - } -} - -function stopProfilerTimerIfRunning(fiber) { - profilerStartTime = -1; -} - -function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { - if (profilerStartTime >= 0) { - var elapsedTime = now$1() - profilerStartTime; - fiber.actualDuration += elapsedTime; - - if (overrideBaseTime) { - fiber.selfBaseDuration = elapsedTime; - } - - profilerStartTime = -1; - } -} - -function transferActualDuration(fiber) { - // Transfer time spent rendering these children so we don't lose it - // after we rerender. This is used as a helper in special cases - // where we should count the work of multiple passes. - var child = fiber.child; - - while (child) { - fiber.actualDuration += child.actualDuration; - child = child.sibling; - } -} - -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 -) { - // 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; - - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(Component) - ); - } - } - } - - 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 (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - try { - nextChildren = renderWithHooks( - current, - workInProgress, - render, - nextProps, - ref, - renderLanes - ); - } finally { - reenableLogs(); - } - } - - setIsRendering(false); - } - - 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 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; - - { - 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. - - workInProgress.tag = SimpleMemoComponent; - workInProgress.type = resolvedType; - - { - validateFunctionComponentInDev(workInProgress, type); - } - - return updateSimpleMemoComponent( - current, - workInProgress, - resolvedType, - nextProps, - updateLanes, - 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", - getComponentName(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 _type = Component.type; - 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", - getComponentName(_type) - ); - } - } - - var currentChild = current.child; // This is always exactly one 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 - - 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, - 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; - - 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 { - 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", - getComponentName(outerMemoType) - ); - } - } - } - } + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - if (current !== null) { - var prevProps = current.memoizedProps; + try { + return updateState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; + InvalidNestedHooksDispatcherOnRerenderInDEV = { + readContext: function(context, observedBits) { + warnInvalidContextAccess(); + return readContext(context, observedBits); + }, + useCallback: function(callback, deps) { + currentHookNameInDev = "useCallback"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateCallback(callback, deps); + }, + useContext: function(context, observedBits) { + currentHookNameInDev = "useContext"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return readContext(context, observedBits); + }, + useEffect: function(create, deps) { + currentHookNameInDev = "useEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateEffect(create, deps); + }, + useImperativeHandle: function(ref, create, deps) { + currentHookNameInDev = "useImperativeHandle"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateImperativeHandle(ref, create, deps); + }, + useLayoutEffect: function(create, deps) { + currentHookNameInDev = "useLayoutEffect"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateLayoutEffect(create, deps); + }, + useMemo: function(create, deps) { + currentHookNameInDev = "useMemo"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - if ( - shallowEqual(prevProps, nextProps) && - current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. - workInProgress.type === current.type - ) { - didReceiveUpdate = false; + try { + return updateMemo(create, deps); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useReducer: function(reducer, initialArg, init) { + currentHookNameInDev = "useReducer"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - 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 accumlated 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; + try { + return rerenderReducer(reducer, initialArg, init); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; } - } - } + }, + useRef: function(initialValue) { + currentHookNameInDev = "useRef"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateRef(); + }, + useState: function(initialState) { + currentHookNameInDev = "useState"; + warnInvalidHookAccess(); + updateHookTypesDev(); + var prevDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV; - return updateFunctionComponent( - current, - workInProgress, - Component, - nextProps, - renderLanes - ); + try { + return rerenderState(initialState); + } finally { + ReactCurrentDispatcher$1.current = prevDispatcher; + } + }, + useDebugValue: function(value, formatterFn) { + currentHookNameInDev = "useDebugValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateDebugValue(); + }, + useDeferredValue: function(value) { + currentHookNameInDev = "useDeferredValue"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderDeferredValue(value); + }, + useTransition: function() { + currentHookNameInDev = "useTransition"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderTransition(); + }, + useMutableSource: function(source, getSnapshot, subscribe) { + currentHookNameInDev = "useMutableSource"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return updateMutableSource(source, getSnapshot, subscribe); + }, + useOpaqueIdentifier: function() { + currentHookNameInDev = "useOpaqueIdentifier"; + warnInvalidHookAccess(); + updateHookTypesDev(); + return rerenderOpaqueIdentifier(); + }, + unstable_isNewReconciler: enableNewReconciler + }; } -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. - // TODO: Figure out what we should do in Blocking mode. - 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; +var now$1 = Scheduler.unstable_now; +var commitTime = 0; +var profilerStartTime = -1; - 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. +function getCommitTime() { + return commitTime; +} - { - markSpawnedWork(OffscreenLane); - } +function recordCommitTime() { + commitTime = now$1(); +} - 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. +function startProfilerTimer(fiber) { + profilerStartTime = now$1(); - 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. + if (fiber.actualStartTime < 0) { + fiber.actualStartTime = now$1(); + } +} - var subtreeRenderLanes = - prevState !== null ? prevState.baseLanes : renderLanes; - pushRenderLanes(workInProgress, subtreeRenderLanes); - } - } else { - // Rendering a visible tree. - var _subtreeRenderLanes; +function stopProfilerTimerIfRunning(fiber) { + profilerStartTime = -1; +} - if (prevState !== null) { - // We're going from hidden -> visible. - _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); +function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) { + if (profilerStartTime >= 0) { + var elapsedTime = now$1() - profilerStartTime; + fiber.actualDuration += elapsedTime; - 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; + if (overrideBaseTime) { + fiber.selfBaseDuration = elapsedTime; } - pushRenderLanes(workInProgress, _subtreeRenderLanes); + profilerStartTime = -1; } +} - 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. - -var updateLegacyHiddenComponent = updateOffscreenComponent; +function transferActualDuration(fiber) { + // Transfer time spent rendering these children so we don't lose it + // after we rerender. This is used as a helper in special cases + // where we should count the work of multiple passes. + var child = fiber.child; -function updateFragment(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + while (child) { + fiber.actualDuration += child.actualDuration; + child = child.sibling; + } } -function updateMode(current, workInProgress, renderLanes) { - var nextChildren = workInProgress.pendingProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; -} +var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; +var didReceiveUpdate = false; +var didWarnAboutBadClass; +var didWarnAboutModulePatternComponent; +var didWarnAboutContextTypeOnFunctionComponent; +var didWarnAboutGetDerivedStateOnFunctionComponent; +var didWarnAboutFunctionRefs; +var didWarnAboutReassigningProps; +var didWarnAboutRevealOrder; +var didWarnAboutTailOptions; -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, +{ + didWarnAboutBadClass = {}; + didWarnAboutModulePatternComponent = {}; + didWarnAboutContextTypeOnFunctionComponent = {}; + didWarnAboutGetDerivedStateOnFunctionComponent = {}; + didWarnAboutFunctionRefs = {}; + didWarnAboutReassigningProps = false; + didWarnAboutRevealOrder = {}; + didWarnAboutTailOptions = {}; +} - var stateNode = workInProgress.stateNode; - stateNode.effectDuration = 0; - stateNode.passiveEffectDuration = 0; +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 + ); } - - var nextProps = workInProgress.pendingProps; - var nextChildren = nextProps.children; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; } -function markRef(current, workInProgress) { - var ref = workInProgress.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. - if ( - (current === null && ref !== null) || - (current !== null && current.ref !== ref) - ) { - // Schedule a Ref effect - workInProgress.flags |= Ref; - } + workInProgress.child = reconcileChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); } -function updateFunctionComponent( +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 @@ -13138,12 +12401,8 @@ function updateFunctionComponent( } } - var context; - - { - var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); - context = getMaskedContext(workInProgress, unmaskedContext); - } + var render = Component.render; + var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent var nextChildren; prepareToReadContext(workInProgress, renderLanes); @@ -13154,22 +12413,22 @@ function updateFunctionComponent( nextChildren = renderWithHooks( current, workInProgress, - Component, + render, nextProps, - context, + ref, renderLanes ); - if (workInProgress.mode & StrictLegacyMode) { + if (workInProgress.mode & StrictMode) { disableLogs(); try { nextChildren = renderWithHooks( current, workInProgress, - Component, + render, nextProps, - context, + ref, renderLanes ); } finally { @@ -13177,455 +12436,437 @@ function updateFunctionComponent( } } - setIsRendering(false); - } + setIsRendering(false); + } + + 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 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; + + { + 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. + + workInProgress.tag = SimpleMemoComponent; + workInProgress.type = resolvedType; + + { + validateFunctionComponentInDev(workInProgress, type); + } + + return updateSimpleMemoComponent( + current, + workInProgress, + resolvedType, + nextProps, + updateLanes, + 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", + getComponentName(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 _type = Component.type; + 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", + getComponentName(_type) + ); + } + } + + var currentChild = current.child; // This is always exactly one 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 + + var compare = Component.compare; + compare = compare !== null ? compare : shallowEqual; - if (current !== null && !didReceiveUpdate) { - bailoutHooks(current, workInProgress, renderLanes); - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } } // React DevTools reads this flag. workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, nextChildren, renderLanes); - return workInProgress.child; + var newChild = createWorkInProgress(currentChild, nextProps); + newChild.ref = workInProgress.ref; + newChild.return = workInProgress; + workInProgress.child = newChild; + return newChild; } -function updateClassComponent( +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 innerPropTypes = Component.propTypes; + var outerMemoType = workInProgress.elementType; - if (innerPropTypes) { - checkPropTypes( - innerPropTypes, - nextProps, // Resolved props - "prop", - getComponentName(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. + 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; - var hasContext; + try { + outerMemoType = init(payload); + } catch (x) { + outerMemoType = null; + } // Inner propTypes will be validated in the function component path. - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + var outerPropTypes = outerMemoType && outerMemoType.propTypes; - prepareToReadContext(workInProgress, renderLanes); - var instance = workInProgress.stateNode; - var shouldUpdate; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + nextProps, // Resolved (SimpleMemoComponent has no defaultProps) + "prop", + getComponentName(outerMemoType) + ); + } + } + } + } - 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 + if (current !== null) { + var prevProps = current.memoizedProps; - workInProgress.flags |= Placement; - } // In the initial pass we might need to construct the instance. + if ( + shallowEqual(prevProps, nextProps) && + current.ref === workInProgress.ref && // Prevent bailout if the implementation changed due to hot reload. + workInProgress.type === current.type + ) { + didReceiveUpdate = false; - 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 - ); + 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 accumlated 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; + } + } } - var nextUnitOfWork = finishClassComponent( + return updateFunctionComponent( current, workInProgress, Component, - shouldUpdate, - hasContext, + nextProps, renderLanes ); - - { - var inst = workInProgress.stateNode; - - 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.", - getComponentName(workInProgress.type) || "a component" - ); - } - - didWarnAboutReassigningProps = true; - } - } - - 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; - - if (!shouldUpdate && !didCaptureError) { - // Context providers should defer to sCU for rendering - if (hasContext) { - invalidateContextProvider(workInProgress, Component, false); - } - - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); - } - - var instance = workInProgress.stateNode; // Rerender - - ReactCurrentOwner$1.current = workInProgress; - var nextChildren; +function updateOffscreenComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; + var prevState = current !== null ? current.memoizedState : null; if ( - didCaptureError && - typeof Component.getDerivedStateFromError !== "function" + nextProps.mode === "hidden" || + nextProps.mode === "unstable-defer-without-hiding" ) { - // 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; - - { - stopProfilerTimerIfRunning(); - } - } else { - { - setIsRendering(true); - nextChildren = instance.render(); - - if (workInProgress.mode & StrictLegacyMode) { - disableLogs(); - - 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 pushHostRootContext(workInProgress) { - var root = workInProgress.stateNode; + if ((workInProgress.mode & ConcurrentMode) === NoMode) { + // In legacy sync mode, don't defer the subtree. Render it now. + // TODO: Figure out what we should do in Blocking mode. + var nextState = { + baseLanes: NoLanes + }; + workInProgress.memoizedState = nextState; + pushRenderLanes(workInProgress, renderLanes); + } else if (!includesSomeLane(renderLanes, OffscreenLane)) { + var nextBaseLanes; - 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 (prevState !== null) { + var prevBaseLanes = prevState.baseLanes; + nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes); + } else { + nextBaseLanes = renderLanes; + } // Schedule this fiber to re-render at offscreen priority. Then bailout. - pushHostContainer(workInProgress, root.containerInfo); -} + { + markSpawnedWork(OffscreenLane); + } -function updateHostRoot(current, workInProgress, renderLanes) { - pushHostRootContext(workInProgress); - var updateQueue = workInProgress.updateQueue; + workInProgress.lanes = workInProgress.childLanes = laneToLanes( + OffscreenLane + ); + var _nextState = { + baseLanes: nextBaseLanes + }; + workInProgress.memoizedState = _nextState; // We're about to bail out, but we need to push this to the stack anyway + // to avoid a push/pop misalignment. - 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." - ); - } + pushRenderLanes(workInProgress, nextBaseLanes); + return null; + } else { + // Rendering at offscreen, so we can clear the base lanes. + var _nextState2 = { + baseLanes: NoLanes + }; + workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out. - 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 subtreeRenderLanes = + prevState !== null ? prevState.baseLanes : renderLanes; + pushRenderLanes(workInProgress, subtreeRenderLanes); + } + } else { + var _subtreeRenderLanes; - var nextChildren = nextState.element; + if (prevState !== null) { + _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes); // Since we're not hidden anymore, reset the state - if (nextChildren === prevChildren) { - return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + 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; + } + + pushRenderLanes(workInProgress, _subtreeRenderLanes); } - if (root.hydrate && enterHydrationState()) { - var child = mountChildFibers( - workInProgress, - null, - nextChildren, - renderLanes - ); - workInProgress.child = child; - var node = child; + 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. - 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); - } +var updateLegacyHiddenComponent = updateOffscreenComponent; +function updateFragment(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateHostComponent(current, workInProgress, renderLanes) { - pushHostContext(workInProgress); +function updateMode(current, workInProgress, renderLanes) { + var nextChildren = workInProgress.pendingProps.children; + reconcileChildren(current, workInProgress, nextChildren, renderLanes); + return workInProgress.child; +} - var type = workInProgress.type; - var nextProps = workInProgress.pendingProps; - var prevProps = current !== null ? current.memoizedProps : null; - var nextChildren = nextProps.children; +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, - 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; + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; } - markRef(current, workInProgress); + var nextProps = workInProgress.pendingProps; + var nextChildren = nextProps.children; reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } -function updateHostText(current, workInProgress) { - // immediately after. +function markRef(current, workInProgress) { + var ref = workInProgress.ref; - return null; + if ( + (current === null && ref !== null) || + (current !== null && current.ref !== ref) + ) { + // Schedule a Ref effect + workInProgress.flags |= Ref; + } } -function mountLazyComponent( - _current, +function updateFunctionComponent( + current, workInProgress, - elementType, - updateLanes, + Component, + nextProps, 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 - - workInProgress.flags |= Placement; - } - - 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. - - workInProgress.type = Component; - var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); - var resolvedProps = resolveDefaultProps(Component, props); - var child; - - switch (resolvedTag) { - case FunctionComponent: { - { - validateFunctionComponentInDev(workInProgress, Component); - workInProgress.type = Component = resolveFunctionForHotReloading( - Component - ); - } - - child = updateFunctionComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; - } - - case ClassComponent: { - { - workInProgress.type = Component = resolveClassForHotReloading( - Component - ); - } - - child = updateClassComponent( - null, - workInProgress, - Component, - resolvedProps, - renderLanes - ); - return child; - } + { + 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; - case ForwardRef: { - { - workInProgress.type = Component = resolveForwardRefForHotReloading( - Component + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(Component) ); } - - 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", - getComponentName(Component) - ); - } - } - } + var context; - child = updateMemoComponent( - null, - workInProgress, - Component, - resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too - updateLanes, - renderLanes - ); - return child; - } + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, true); + context = getMaskedContext(workInProgress, unmaskedContext); } - var hint = ""; + var nextChildren; + prepareToReadContext(workInProgress, renderLanes); { - if ( - Component !== null && - typeof Component === "object" && - Component.$$typeof === REACT_LAZY_TYPE - ) { - hint = " Did you wrap a component in React.lazy() more than once?"; + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + + if (workInProgress.mode & StrictMode) { + disableLogs(); + + try { + nextChildren = renderWithHooks( + current, + workInProgress, + Component, + nextProps, + context, + renderLanes + ); + } finally { + reenableLogs(); + } } - } // 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 - ); + setIsRendering(false); } + + 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 mountIncompleteClassComponent( - _current, +function updateClassComponent( + 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 - - workInProgress.flags |= Placement; - } // Promote the fiber to a class and try rendering again. + { + 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.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent` - // Push context providers early to prevent context stack mismatches. + if (innerPropTypes) { + checkPropTypes( + innerPropTypes, + nextProps, // Resolved props + "prop", + getComponentName(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. @@ -13639,2644 +12880,2412 @@ function mountIncompleteClassComponent( } prepareToReadContext(workInProgress, renderLanes); - constructClassInstance(workInProgress, Component, nextProps); - mountClassInstance(workInProgress, Component, nextProps, renderLanes); - return finishClassComponent( - null, - workInProgress, - Component, - true, - hasContext, - renderLanes - ); -} - -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 - - 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 ( - Component.prototype && - typeof Component.prototype.render === "function" - ) { - var componentName = getComponentName(Component) || "Unknown"; - - 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 - ); + var instance = workInProgress.stateNode; + var shouldUpdate; - didWarnAboutBadClass[componentName] = true; - } - } + 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 - if (workInProgress.mode & StrictLegacyMode) { - ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); - } + workInProgress.flags |= Placement; + } // In the initial pass we might need to construct the instance. - setIsRendering(true); - ReactCurrentOwner$1.current = workInProgress; - value = renderWithHooks( - null, + 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, - props, - context, + nextProps, renderLanes ); - setIsRendering(false); - } // React DevTools reads this flag. + } else { + shouldUpdate = updateClassInstance( + current, + workInProgress, + Component, + nextProps, + renderLanes + ); + } - workInProgress.flags |= PerformedWork; + var nextUnitOfWork = finishClassComponent( + current, + workInProgress, + Component, + shouldUpdate, + hasContext, + renderLanes + ); { - // 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 = getComponentName(Component) || "Unknown"; + var inst = workInProgress.stateNode; - if (!didWarnAboutModulePatternComponent[_componentName]) { + if (shouldUpdate && inst.props !== nextProps) { + if (!didWarnAboutReassigningProps) { 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 + "It looks like %s is reassigning its own `this.props` while rendering. " + + "This is not supported and can lead to confusing bugs.", + getComponentName(workInProgress.type) || "a component" ); - - didWarnAboutModulePatternComponent[_componentName] = true; } + + didWarnAboutReassigningProps = true; } } - 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 = getComponentName(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 - ); + return nextUnitOfWork; +} - didWarnAboutModulePatternComponent[_componentName2] = true; - } - } // Proceed under the assumption that this is a class instance +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; - workInProgress.tag = ClassComponent; // Throw out any hooks that were used. + if (!shouldUpdate && !didCaptureError) { + // Context providers should defer to sCU for rendering + if (hasContext) { + invalidateContextProvider(workInProgress, Component, false); + } - 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 bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - var hasContext = false; + var instance = workInProgress.stateNode; // Rerender - if (isContextProvider(Component)) { - hasContext = true; - pushContextProvider(workInProgress); - } else { - hasContext = false; - } + ReactCurrentOwner$1.current = workInProgress; + var nextChildren; - workInProgress.memoizedState = - value.state !== null && value.state !== undefined ? value.state : null; - initializeUpdateQueue(workInProgress); - var getDerivedStateFromProps = Component.getDerivedStateFromProps; + 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 (typeof getDerivedStateFromProps === "function") { - applyDerivedStateFromProps( - workInProgress, - Component, - getDerivedStateFromProps, - props - ); + { + stopProfilerTimerIfRunning(); } - - 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 (workInProgress.mode & StrictLegacyMode) { + setIsRendering(true); + nextChildren = instance.render(); + + if (workInProgress.mode & StrictMode) { disableLogs(); try { - value = renderWithHooks( - null, - workInProgress, - Component, - props, - context, - renderLanes - ); + instance.render(); } finally { reenableLogs(); } } + + setIsRendering(false); } + } // React DevTools reads this flag. - reconcileChildren(null, workInProgress, value, renderLanes); + workInProgress.flags |= PerformedWork; - { - validateFunctionComponentInDev(workInProgress, Component); - } + 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. -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 (hasContext) { + invalidateContextProvider(workInProgress, Component, true); + } - if (workInProgress.ref !== null) { - var info = ""; - var ownerName = getCurrentFiberOwnerNameInDevOrNull(); + return workInProgress.child; +} - if (ownerName) { - info += "\n\nCheck the render method of `" + ownerName + "`."; - } +function pushHostRootContext(workInProgress) { + var root = workInProgress.stateNode; - var warningKey = ownerName || workInProgress._debugID || ""; - var debugSource = workInProgress._debugSource; + 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 (debugSource) { - warningKey = debugSource.fileName + ":" + debugSource.lineNumber; - } + pushHostContainer(workInProgress, root.containerInfo); +} - if (!didWarnAboutFunctionRefs[warningKey]) { - didWarnAboutFunctionRefs[warningKey] = true; +function updateHostRoot(current, workInProgress, renderLanes) { + pushHostRootContext(workInProgress); + var updateQueue = workInProgress.updateQueue; - error( - "Function components cannot be given refs. " + - "Attempts to access this ref will fail. " + - "Did you mean to use React.forwardRef()?%s", - info - ); - } - } + 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 (typeof Component.getDerivedStateFromProps === "function") { - var _componentName3 = getComponentName(Component) || "Unknown"; + var nextProps = workInProgress.pendingProps; + var prevState = workInProgress.memoizedState; + var prevChildren = prevState !== null ? prevState.element : null; + cloneUpdateQueue(current, workInProgress); + processUpdateQueue(workInProgress, nextProps, null, renderLanes); + var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property + // being called "element". - if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { - error( - "%s: Function components do not support getDerivedStateFromProps.", - _componentName3 - ); + var nextChildren = nextState.element; - didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; - } - } + if (nextChildren === prevChildren) { + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); + } - if ( - typeof Component.contextType === "object" && - Component.contextType !== null - ) { - var _componentName4 = getComponentName(Component) || "Unknown"; + var root = workInProgress.stateNode; - if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { - error( - "%s: Function components do not support contextType.", - _componentName4 - ); + if (root.hydrate && enterHydrationState()) { + var child = mountChildFibers( + workInProgress, + null, + nextChildren, + renderLanes + ); + workInProgress.child = child; + var node = child; - didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; - } + 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); } -} - -var SUSPENDED_MARKER = { - dehydrated: null, - retryLane: NoLane -}; -function mountSuspenseOffscreenState(renderLanes) { - return { - baseLanes: renderLanes, - cachePool: getSuspendedCachePool() - }; + 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 updateHostComponent(current, workInProgress, renderLanes) { + pushHostContext(workInProgress); -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 type = workInProgress.type; + var nextProps = workInProgress.pendingProps; + var prevProps = current !== null ? current.memoizedProps : null; + var nextChildren = nextProps.children; - 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 (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 hasSuspenseContext(suspenseContext, ForceSuspenseFallback); + markRef(current, workInProgress); + 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 updateHostText(current, workInProgress) { + // immediately after. + + return null; } -function updateSuspenseComponent(current, workInProgress, renderLanes) { - var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. +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 (shouldSuspend(workInProgress)) { - workInProgress.flags |= DidCapture; - } + workInProgress.flags |= Placement; } - var suspenseContext = suspenseStackCursor.current; - var showFallback = false; - var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; + 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 (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. - // Boundaries without fallbacks or should be avoided are not considered since - // they cannot handle preferred fallback states. - if ( - nextProps.fallback !== undefined && - nextProps.unstable_avoidThisFallback !== true - ) { - suspenseContext = addSubtreeSuspenseContext( - suspenseContext, - InvisibleParentSuspenseContext + workInProgress.type = Component; + var resolvedTag = (workInProgress.tag = resolveLazyComponentTag(Component)); + var resolvedProps = resolveDefaultProps(Component, props); + var child; + + switch (resolvedTag) { + case FunctionComponent: { + { + validateFunctionComponentInDev(workInProgress, Component); + workInProgress.type = Component = resolveFunctionForHotReloading( + 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) { - // Initial mount - // If we're currently hydrating, try to hydrate this boundary. - // But only if this has a fallback. - if (nextProps.fallback !== undefined); - - var nextPrimaryChildren = nextProps.children; - var nextFallbackChildren = nextProps.fallback; - 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( + child = updateFunctionComponent( + null, workInProgress, - nextPrimaryChildren, - nextFallbackChildren, - renderLanes - ); - - var _primaryChildFragment = workInProgress.child; - _primaryChildFragment.memoizedState = mountSuspenseOffscreenState( + Component, + resolvedProps, 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. - - workInProgress.lanes = SomeRetryLane; + return child; + } + case ClassComponent: { { - markSpawnedWork(SomeRetryLane); + workInProgress.type = Component = resolveClassForHotReloading( + Component + ); } - return _fallbackFragment; - } else { - return mountSuspensePrimaryChildren( + child = updateClassComponent( + null, workInProgress, - nextPrimaryChildren, + Component, + resolvedProps, renderLanes ); + return child; } - } 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 (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 + case ForwardRef: { + { + workInProgress.type = Component = resolveForwardRefForHotReloading( + Component ); - - 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; - var _fallbackChildFragment2 = updateSuspenseFallbackChildren( - current, - workInProgress, - _nextPrimaryChildren4, - _nextFallbackChildren3, - renderLanes - ); + child = updateForwardRef( + null, + workInProgress, + Component, + resolvedProps, + renderLanes + ); + return child; + } - 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. + case MemoComponent: { + { + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = Component.propTypes; - workInProgress.memoizedState = SUSPENDED_MARKER; - return _fallbackChildFragment2; - } else { - // Still haven't timed out. Continue rendering the children, like we - // normally do. - var _nextPrimaryChildren5 = nextProps.children; + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + resolvedProps, // Resolved for outer only + "prop", + getComponentName(Component) + ); + } + } + } - var _primaryChildFragment6 = updateSuspensePrimaryChildren( - current, - workInProgress, - _nextPrimaryChildren5, - renderLanes - ); + child = updateMemoComponent( + null, + workInProgress, + Component, + resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too + updateLanes, + renderLanes + ); + return child; + } + } - workInProgress.memoizedState = null; - return _primaryChildFragment6; - } + 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 + ); } } -function mountSuspensePrimaryChildren( +function mountIncompleteClassComponent( + _current, workInProgress, - primaryChildren, + Component, + nextProps, 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; -} + 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 -function mountSuspenseFallbackChildren( - workInProgress, - primaryChildren, - fallbackChildren, - renderLanes -) { - var mode = workInProgress.mode; - var progressedPrimaryFragment = workInProgress.child; - var primaryChildProps = { - mode: "hidden", - children: primaryChildren - }; - var primaryChildFragment; - var fallbackChildFragment; + workInProgress.flags |= Placement; + } // Promote the fiber to a class and try rendering again. - if ((mode & BlockingMode) === 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; + 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 & 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 hasContext; - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + if (isContextProvider(Component)) { + hasContext = true; + pushContextProvider(workInProgress); } else { - primaryChildFragment = createFiberFromOffscreen( - primaryChildProps, - mode, - NoLanes, - null - ); - fallbackChildFragment = createFiberFromFragment( - fallbackChildren, - mode, - renderLanes, - null - ); + hasContext = false; } - 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); + prepareToReadContext(workInProgress, renderLanes); + constructClassInstance(workInProgress, Component, nextProps); + mountClassInstance(workInProgress, Component, nextProps, renderLanes); + return finishClassComponent( + null, + workInProgress, + Component, + true, + hasContext, + renderLanes + ); } -function updateSuspensePrimaryChildren( - current, +function mountIndeterminateComponent( + _current, workInProgress, - primaryChildren, + Component, renderLanes ) { - var currentPrimaryChildFragment = current.child; - var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; - var primaryChildFragment = createWorkInProgressOffscreenFiber( - currentPrimaryChildFragment, - { - mode: "visible", - children: primaryChildren - } - ); + 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 ((workInProgress.mode & BlockingMode) === NoMode) { - primaryChildFragment.lanes = renderLanes; + workInProgress.flags |= Placement; } - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = null; - - if (currentFallbackChildFragment !== null) { - // Delete the fallback child fragment - var deletions = workInProgress.deletions; + var props = workInProgress.pendingProps; + var context; - if (deletions === null) { - workInProgress.deletions = [currentFallbackChildFragment]; - workInProgress.flags |= ChildDeletion; - } else { - deletions.push(currentFallbackChildFragment); - } + { + var unmaskedContext = getUnmaskedContext(workInProgress, Component, false); + context = getMaskedContext(workInProgress, unmaskedContext); } - workInProgress.child = primaryChildFragment; - return primaryChildFragment; -} - -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; - - if ( - // In legacy mode, we commit the primary tree as if it successfully - // completed, even though it's in an inconsistent state. - (mode & BlockingMode) === 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; + prepareToReadContext(workInProgress, renderLanes); + var value; - 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. + { + if ( + Component.prototype && + typeof Component.prototype.render === "function" + ) { + var componentName = getComponentName(Component) || "Unknown"; - 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 (!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 + ); - primaryChildFragment.subtreeFlags = - currentPrimaryChildFragment.subtreeFlags & StaticMask; - } + didWarnAboutBadClass[componentName] = true; + } + } - var fallbackChildFragment; + if (workInProgress.mode & StrictMode) { + ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null); + } - if (currentFallbackChildFragment !== null) { - fallbackChildFragment = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren + setIsRendering(true); + ReactCurrentOwner$1.current = workInProgress; + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + 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. + setIsRendering(false); + } // React DevTools reads this flag. - fallbackChildFragment.flags |= Placement; - } + workInProgress.flags |= PerformedWork; - fallbackChildFragment.return = workInProgress; - primaryChildFragment.return = workInProgress; - primaryChildFragment.sibling = fallbackChildFragment; - workInProgress.child = primaryChildFragment; - return fallbackChildFragment; -} + { + // 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 = getComponentName(Component) || "Unknown"; -function scheduleWorkOnFiber(fiber, renderLanes) { - fiber.lanes = mergeLanes(fiber.lanes, renderLanes); - var alternate = fiber.alternate; + 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 (alternate !== null) { - alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + didWarnAboutModulePatternComponent[_componentName] = true; + } + } } - scheduleWorkOnParentPath(fiber.return, renderLanes); -} - -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 ( + // 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 = getComponentName(Component) || "Unknown"; - while (node !== null) { - if (node.tag === SuspenseComponent) { - var state = node.memoizedState; + 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 + ); - if (state !== null) { - scheduleWorkOnFiber(node, renderLanes); + didWarnAboutModulePatternComponent[_componentName2] = true; } - } 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; - } + } // Proceed under the assumption that this is a class instance - if (node === workInProgress) { - return; + 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; } - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } + workInProgress.memoizedState = + value.state !== null && value.state !== undefined ? value.state : null; + initializeUpdateQueue(workInProgress); + var getDerivedStateFromProps = Component.getDerivedStateFromProps; - node = node.return; + if (typeof getDerivedStateFromProps === "function") { + applyDerivedStateFromProps( + workInProgress, + Component, + getDerivedStateFromProps, + props + ); } - node.sibling.return = node.return; - node = node.sibling; - } -} + 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; -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 (workInProgress.mode & StrictMode) { + disableLogs(); - while (row !== null) { - var currentRow = row.alternate; // New rows can't be content rows. + try { + value = renderWithHooks( + null, + workInProgress, + Component, + props, + context, + renderLanes + ); + } finally { + reenableLogs(); + } + } + } - if (currentRow !== null && findFirstSuspended(currentRow) === null) { - lastContentRow = row; + reconcileChildren(null, workInProgress, value, renderLanes); + + { + validateFunctionComponentInDev(workInProgress, Component); } - row = row.sibling; + return workInProgress.child; } - - return lastContentRow; } -function validateRevealOrder(revealOrder) { +function validateFunctionComponentInDev(workInProgress, Component) { { - if ( - revealOrder !== undefined && - revealOrder !== "forwards" && - revealOrder !== "backwards" && - revealOrder !== "together" && - !didWarnAboutRevealOrder[revealOrder] - ) { - didWarnAboutRevealOrder[revealOrder] = true; + if (Component) { + if (Component.childContextTypes) { + error( + "%s(...): childContextTypes cannot be defined on a function component.", + Component.displayName || Component.name || "Component" + ); + } + } - 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() - ); + if (workInProgress.ref !== null) { + var info = ""; + var ownerName = getCurrentFiberOwnerNameInDevOrNull(); - break; - } + if (ownerName) { + info += "\n\nCheck the render method of `" + ownerName + "`."; + } - 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() - ); + var warningKey = ownerName || workInProgress._debugID || ""; + var debugSource = workInProgress._debugSource; - break; - } + if (debugSource) { + warningKey = debugSource.fileName + ":" + debugSource.lineNumber; + } - default: - error( - '"%s" is not a supported revealOrder on . ' + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder - ); + if (!didWarnAboutFunctionRefs[warningKey]) { + didWarnAboutFunctionRefs[warningKey] = true; - break; - } - } else { error( - "%s is not a supported value for revealOrder on . " + - 'Did you mean "together", "forwards" or "backwards"?', - revealOrder + "Function components cannot be given refs. " + + "Attempts to access this ref will fail. " + + "Did you mean to use React.forwardRef()?%s", + info ); } } - } -} -function validateTailOptions(tailMode, revealOrder) { - { - if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { - if (tailMode !== "collapsed" && tailMode !== "hidden") { - didWarnAboutTailOptions[tailMode] = true; + if (typeof Component.getDerivedStateFromProps === "function") { + var _componentName3 = getComponentName(Component) || "Unknown"; + if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) { error( - '"%s" is not a supported value for tail on . ' + - 'Did you mean "collapsed" or "hidden"?', - tailMode + "%s: Function components do not support getDerivedStateFromProps.", + _componentName3 ); - } else if (revealOrder !== "forwards" && revealOrder !== "backwards") { - didWarnAboutTailOptions[tailMode] = true; + didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true; + } + } + + if ( + typeof Component.contextType === "object" && + Component.contextType !== null + ) { + var _componentName4 = getComponentName(Component) || "Unknown"; + + if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) { error( - ' is only valid if revealOrder is ' + - '"forwards" or "backwards". ' + - 'Did you mean to specify revealOrder="forwards"?', - tailMode + "%s: Function components do not support contextType.", + _componentName4 ); + + didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true; } } } } -function validateSuspenseListNestedChild(childSlot, index) { - { - var isArray = Array.isArray(childSlot); - var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; +var SUSPENDED_MARKER = { + dehydrated: null, + retryLane: NoLane +}; - if (isArray || isIterable) { - var type = isArray ? "array" : "iterable"; +function mountSuspenseOffscreenState(renderLanes) { + return { + baseLanes: renderLanes + }; +} - 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 updateSuspenseOffscreenState(prevOffscreenState, renderLanes) { + return { + baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes) + }; +} // TODO: Probably should inline this back + +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; + 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. - return true; + return hasSuspenseContext(suspenseContext, ForceSuspenseFallback); } -function validateSuspenseListChildren(children, revealOrder) { - { - if ( - (revealOrder === "forwards" || revealOrder === "backwards") && - children !== undefined && - children !== null && - children !== false - ) { - if (Array.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; +function getRemainingWorkInPrimaryTree(current, renderLanes) { + // TODO: Should not remove render lanes that were pinged during this render + return removeLanes(current.childLanes, renderLanes); +} - for (; !step.done; step = childrenIterator.next()) { - if (!validateSuspenseListNestedChild(step.value, _i)) { - return; - } +function updateSuspenseComponent(current, workInProgress, renderLanes) { + var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend. - _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 - ); - } - } + { + if (shouldSuspend(workInProgress)) { + workInProgress.flags |= DidCapture; } } -} -function initSuspenseListRenderState( - workInProgress, - isBackwards, - tail, - lastContentRow, - tailMode -) { - var renderState = workInProgress.memoizedState; + var suspenseContext = suspenseStackCursor.current; + var showFallback = false; + var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags; - if (renderState === null) { - workInProgress.memoizedState = { - isBackwards: isBackwards, - rendering: null, - renderingStartTime: 0, - last: lastContentRow, - tail: tail, - tailMode: tailMode - }; + 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 { - // 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; + // 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. + // Boundaries without fallbacks or should be avoided are not considered since + // they cannot handle preferred fallback states. + if ( + nextProps.fallback !== undefined && + nextProps.unstable_avoidThisFallback !== true + ) { + suspenseContext = addSubtreeSuspenseContext( + suspenseContext, + InvisibleParentSuspenseContext + ); + } + } } -} // 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 - ); + 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 (shouldForceFallback) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - workInProgress.flags |= DidCapture; - } else { - var didSuspendBefore = - current !== null && (current.flags & DidCapture) !== NoFlags; + if (current === null) { + // Initial mount + // If we're currently hydrating, try to hydrate this boundary. + // But only if this has a fallback. + if (nextProps.fallback !== undefined); - 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( + var nextPrimaryChildren = nextProps.children; + var nextFallbackChildren = nextProps.fallback; + + if (showFallback) { + var fallbackFragment = mountSuspenseFallbackChildren( workInProgress, - workInProgress.child, + 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 ); - } - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); - } + 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. - pushSuspenseContext(workInProgress, suspenseContext); + workInProgress.lanes = SomeRetryLane; - if ((workInProgress.mode & BlockingMode) === 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; + { + markSpawnedWork(SomeRetryLane); + } + + return _fallbackFragment; + } else { + return mountSuspensePrimaryChildren( + workInProgress, + nextPrimaryChildren, + renderLanes + ); + } } else { - switch (revealOrder) { - case "forwards": { - var lastContentRow = findLastContentRow(workInProgress.child); - var tail; + // This is an update. + // If the current fiber has a SuspenseState, that means it's already showing + // a fallback. + var prevState = current.memoizedState; - 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; - } + if (prevState !== null) { + if (showFallback) { + var _nextFallbackChildren2 = nextProps.fallback; + var _nextPrimaryChildren2 = nextProps.children; - initSuspenseListRenderState( + var _fallbackChildFragment = updateSuspenseFallbackChildren( + current, workInProgress, - false, // isBackwards - tail, - lastContentRow, - tailMode + _nextPrimaryChildren2, + _nextFallbackChildren2, + renderLanes ); - 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. + 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 (currentRow !== null && findFirstSuspended(currentRow) === null) { - // This is the beginning of the main content. - workInProgress.child = row; - break; - } + var _primaryChildFragment4 = updateSuspensePrimaryChildren( + current, + workInProgress, + _nextPrimaryChildren3, + renderLanes + ); - var nextRow = row.sibling; - row.sibling = _tail; - _tail = row; - row = nextRow; - } // TODO: If workInProgress.child is null, we can continue on the tail immediately. + 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; - initSuspenseListRenderState( + var _fallbackChildFragment2 = updateSuspenseFallbackChildren( + current, workInProgress, - true, // isBackwards - _tail, - null, // last - tailMode + _nextPrimaryChildren4, + _nextFallbackChildren3, + renderLanes ); - break; - } - case "together": { - initSuspenseListRenderState( + 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, - false, // isBackwards - null, // tail - null, // last - undefined + _nextPrimaryChildren5, + renderLanes ); - break; - } - default: { - // The default reveal order is the same as not having - // a boundary. workInProgress.memoizedState = null; + return _primaryChildFragment6; } } } +} - return workInProgress.child; +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; } -function updatePortalComponent(current, workInProgress, renderLanes) { - pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); - var nextChildren = workInProgress.pendingProps; +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 (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 + if ((mode & BlockingMode) === 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; + } + + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null ); } else { - reconcileChildren(current, workInProgress, nextChildren, renderLanes); + primaryChildFragment = createFiberFromOffscreen( + primaryChildProps, + mode, + NoLanes, + null + ); + fallbackChildFragment = createFiberFromFragment( + fallbackChildren, + mode, + renderLanes, + null + ); } - return workInProgress.child; + primaryChildFragment.return = workInProgress; + fallbackChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -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; - - { - if (!("value" in newProps)) { - if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { - hasWarnedAboutUsingNoValuePropOnContextProvider = true; +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); +} - error( - "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" - ); - } +function updateSuspensePrimaryChildren( + current, + workInProgress, + primaryChildren, + renderLanes +) { + var currentPrimaryChildFragment = current.child; + var currentFallbackChildFragment = currentPrimaryChildFragment.sibling; + var primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + { + mode: "visible", + children: primaryChildren } + ); - var providerPropTypes = workInProgress.type.propTypes; - - if (providerPropTypes) { - checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); - } + if ((workInProgress.mode & BlockingMode) === NoMode) { + primaryChildFragment.lanes = renderLanes; } - pushProvider(workInProgress, context, newValue); - - if (oldProps !== null) { - var oldValue = oldProps.value; - var changedBits = calculateChangedBits(context, newValue, oldValue); + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = null; - if (changedBits === 0) { - // 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, changedBits, renderLanes); - } + if (currentFallbackChildFragment !== null) { + // Delete the fallback child fragment + currentFallbackChildFragment.nextEffect = null; + currentFallbackChildFragment.flags = Deletion; + workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChildFragment; } - var newChildren = newProps.children; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; + workInProgress.child = primaryChildFragment; + return primaryChildFragment; } -var hasWarnedAboutUsingContextAsConsumer = false; - -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. +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; - { - 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 ( + // In legacy mode, we commit the primary tree as if it successfully + // completed, even though it's in an inconsistent state. + (mode & BlockingMode) === 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; - 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; - } - } + 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 effect during the first pass. + // However, since we're going to remain on the fallback, we no longer want + // to delete it. So we need to remove it from the list. Deletions are stored + // on the same list as effects. We want to keep the effects from the primary + // tree. So we copy the primary child fragment's effect list, which does not + // include the fallback deletion effect. - var newProps = workInProgress.pendingProps; - var render = newProps.children; + var progressedLastEffect = primaryChildFragment.lastEffect; - { - 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 (progressedLastEffect !== null) { + workInProgress.firstEffect = primaryChildFragment.firstEffect; + workInProgress.lastEffect = progressedLastEffect; + progressedLastEffect.nextEffect = null; + } else { + // TODO: Reset this somewhere else? Lol legacy mode is so weird. + workInProgress.firstEffect = workInProgress.lastEffect = null; } + } else { + primaryChildFragment = createWorkInProgressOffscreenFiber( + currentPrimaryChildFragment, + primaryChildProps + ); } - prepareToReadContext(workInProgress, renderLanes); - var newValue = readContext(context, newProps.unstable_observedBits); - var newChildren; - - { - ReactCurrentOwner$1.current = workInProgress; - setIsRendering(true); - newChildren = render(newValue); - setIsRendering(false); - } // React DevTools reads this flag. - - workInProgress.flags |= PerformedWork; - reconcileChildren(current, workInProgress, newChildren, renderLanes); - return workInProgress.child; -} - -function markWorkInProgressReceivedUpdate() { - didReceiveUpdate = true; -} + var fallbackChildFragment; -function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { - if (current !== null) { - // Reuse previous dependencies - workInProgress.dependencies = current.dependencies; - } + 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. - { - // Don't update "base" render times for bailouts. - stopProfilerTimerIfRunning(); + fallbackChildFragment.flags |= Placement; } - 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; - } else { - // This fiber doesn't have work, but its subtree does. Clone the child - // fibers and continue. - cloneChildFibers(current, workInProgress); - return workInProgress.child; - } + fallbackChildFragment.return = workInProgress; + primaryChildFragment.return = workInProgress; + primaryChildFragment.sibling = fallbackChildFragment; + workInProgress.child = primaryChildFragment; + return fallbackChildFragment; } -function remountFiber(current, oldWorkInProgress, newWorkInProgress) { - { - var returnFiber = oldWorkInProgress.return; - - if (returnFiber === null) { - throw new Error("Cannot swap the root fiber."); - } // Disconnect from the old current. - // It will get deleted. - - current.alternate = null; - oldWorkInProgress.alternate = null; // Connect to the new tree. +function scheduleWorkOnFiber(fiber, renderLanes) { + fiber.lanes = mergeLanes(fiber.lanes, renderLanes); + var alternate = fiber.alternate; - newWorkInProgress.index = oldWorkInProgress.index; - newWorkInProgress.sibling = oldWorkInProgress.sibling; - newWorkInProgress.return = oldWorkInProgress.return; - newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. + if (alternate !== null) { + alternate.lanes = mergeLanes(alternate.lanes, renderLanes); + } - if (oldWorkInProgress === returnFiber.child) { - returnFiber.child = newWorkInProgress; - } else { - var prevSibling = returnFiber.child; + scheduleWorkOnParentPath(fiber.return, renderLanes); +} - if (prevSibling === null) { - throw new Error("Expected parent to have a child."); - } +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; - while (prevSibling.sibling !== oldWorkInProgress) { - prevSibling = prevSibling.sibling; + while (node !== null) { + if (node.tag === SuspenseComponent) { + var state = node.memoizedState; - if (prevSibling === null) { - throw new Error("Expected to find the previous sibling."); - } + 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; + } - 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 (node === workInProgress) { + return; + } - var deletions = returnFiber.deletions; + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - if (deletions === null) { - returnFiber.deletions = [current]; - returnFiber.flags |= ChildDeletion; - } else { - deletions.push(current); + node = node.return; } - newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - - return newWorkInProgress; + node.sibling.return = node.return; + node = node.sibling; } } -function beginWork(current, workInProgress, renderLanes) { - var updateLanes = workInProgress.lanes; +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 (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 - ) - ); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. + + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + lastContentRow = row; } + + row = row.sibling; } - if (current !== null) { - var oldProps = current.memoizedProps; - var newProps = workInProgress.pendingProps; + return lastContentRow; +} +function validateRevealOrder(revealOrder) { + { if ( - oldProps !== newProps || - hasContextChanged() || // Force a re-render if the implementation changed due to hot reload: - workInProgress.type !== current.type + revealOrder !== undefined && + revealOrder !== "forwards" && + revealOrder !== "backwards" && + revealOrder !== "together" && + !didWarnAboutRevealOrder[revealOrder] ) { - // 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; + didWarnAboutRevealOrder[revealOrder] = true; - case ClassComponent: { - var Component = workInProgress.type; + 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() + ); - if (isContextProvider(Component)) { - pushContextProvider(workInProgress); + break; } - 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 + 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 (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; + break; } - break; - - case SuspenseComponent: { - var state = workInProgress.memoizedState; - - 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. - - var primaryChildFragment = workInProgress.child; - var primaryChildLanes = primaryChildFragment.childLanes; - - 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 { - return null; - } - } - } else { - pushSuspenseContext( - workInProgress, - setDefaultShallowSuspenseContext(suspenseStackCursor.current) + default: + error( + '"%s" is not a supported revealOrder on . ' + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder ); - } - break; + break; } + } else { + error( + "%s is not a supported value for revealOrder on . " + + 'Did you mean "together", "forwards" or "backwards"?', + revealOrder + ); + } + } + } +} + +function validateTailOptions(tailMode, revealOrder) { + { + if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) { + if (tailMode !== "collapsed" && tailMode !== "hidden") { + didWarnAboutTailOptions[tailMode] = true; - case SuspenseListComponent: { - var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; + 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 _hasChildWork = includesSomeLane( - renderLanes, - workInProgress.childLanes - ); + error( + ' is only valid if revealOrder is ' + + '"forwards" or "backwards". ' + + 'Did you mean to specify revealOrder="forwards"?', + tailMode + ); + } + } + } +} - 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 validateSuspenseListNestedChild(childSlot, index) { + { + var isArray = Array.isArray(childSlot); + var isIterable = !isArray && typeof getIteratorFn(childSlot) === "function"; - 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. + if (isArray || isIterable) { + var type = isArray ? "array" : "iterable"; - var renderState = workInProgress.memoizedState; + error( + "A nested %s was passed to row #%s in . Wrap it in " + + "an additional SuspenseList to configure its revealOrder: " + + " ... " + + "{%s} ... " + + "", + type, + index, + type + ); - 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; - } + return false; + } + } - pushSuspenseContext(workInProgress, suspenseStackCursor.current); + return true; +} - 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; +function validateSuspenseListChildren(children, revealOrder) { + { + if ( + (revealOrder === "forwards" || revealOrder === "backwards") && + children !== undefined && + children !== null && + children !== false + ) { + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + if (!validateSuspenseListNestedChild(children[i], i)) { + return; } } + } else { + var iteratorFn = getIteratorFn(children); - 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 (typeof iteratorFn === "function") { + var childrenIterator = iteratorFn.call(children); - 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 (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 + ); + } } } + } +} + +function initSuspenseListRenderState( + workInProgress, + isBackwards, + tail, + lastContentRow, + tailMode, + lastEffectBeforeRendering +) { + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + workInProgress.memoizedState = { + isBackwards: isBackwards, + rendering: null, + renderingStartTime: 0, + last: lastContentRow, + tail: tail, + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering + }; } 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. + // 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; + renderState.lastEffect = lastEffectBeforeRendering; + } +} // 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. - workInProgress.lanes = NoLanes; +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 + ); - switch (workInProgress.tag) { - case IndeterminateComponent: { - return mountIndeterminateComponent( - current, - workInProgress, - workInProgress.type, - renderLanes - ); - } + if (shouldForceFallback) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback + ); + workInProgress.flags |= DidCapture; + } else { + var didSuspendBefore = + current !== null && (current.flags & DidCapture) !== NoFlags; - case LazyComponent: { - var elementType = workInProgress.elementType; - return mountLazyComponent( - current, + 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, - elementType, - updateLanes, + workInProgress.child, 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, - renderLanes - ); - } + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + } - case ClassComponent: { - var _Component2 = workInProgress.type; - var _unresolvedProps = workInProgress.pendingProps; + pushSuspenseContext(workInProgress, suspenseContext); - var _resolvedProps = - workInProgress.elementType === _Component2 - ? _unresolvedProps - : resolveDefaultProps(_Component2, _unresolvedProps); + if ((workInProgress.mode & BlockingMode) === 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; - return updateClassComponent( - current, - workInProgress, - _Component2, - _resolvedProps, - renderLanes - ); - } + 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; + } - case HostRoot: - return updateHostRoot(current, workInProgress, renderLanes); + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + tail, + lastContentRow, + tailMode, + workInProgress.lastEffect + ); + break; + } - case HostComponent: - return updateHostComponent(current, workInProgress, renderLanes); + 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 HostText: - return updateHostText(); + while (row !== null) { + var currentRow = row.alternate; // New rows can't be content rows. - case SuspenseComponent: - return updateSuspenseComponent(current, workInProgress, renderLanes); + if (currentRow !== null && findFirstSuspended(currentRow) === null) { + // This is the beginning of the main content. + workInProgress.child = row; + break; + } - case HostPortal: - return updatePortalComponent(current, workInProgress, renderLanes); + var nextRow = row.sibling; + row.sibling = _tail; + _tail = row; + row = nextRow; + } // TODO: If workInProgress.child is null, we can continue on the tail immediately. - case ForwardRef: { - var type = workInProgress.type; - var _unresolvedProps2 = workInProgress.pendingProps; + initSuspenseListRenderState( + workInProgress, + true, // isBackwards + _tail, + null, // last + tailMode, + workInProgress.lastEffect + ); + break; + } - var _resolvedProps2 = - workInProgress.elementType === type - ? _unresolvedProps2 - : resolveDefaultProps(type, _unresolvedProps2); + case "together": { + initSuspenseListRenderState( + workInProgress, + false, // isBackwards + null, // tail + null, // last + undefined, + workInProgress.lastEffect + ); + break; + } - return updateForwardRef( - current, - workInProgress, - type, - _resolvedProps2, - renderLanes - ); + default: { + // The default reveal order is the same as not having + // a boundary. + workInProgress.memoizedState = null; + } } + } - case Fragment: - return updateFragment(current, workInProgress, renderLanes); - - case Mode: - return updateMode(current, workInProgress, renderLanes); + return workInProgress.child; +} - case Profiler: - return updateProfiler(current, workInProgress, renderLanes); +function updatePortalComponent(current, workInProgress, renderLanes) { + pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo); + var nextChildren = workInProgress.pendingProps; - case ContextProvider: - return updateContextProvider(current, workInProgress, renderLanes); + 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); + } - case ContextConsumer: - return updateContextConsumer(current, workInProgress, renderLanes); + return workInProgress.child; +} - case MemoComponent: { - var _type2 = workInProgress.type; - var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. +var hasWarnedAboutUsingNoValuePropOnContextProvider = false; - var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); +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; - { - if (workInProgress.type !== workInProgress.elementType) { - var outerPropTypes = _type2.propTypes; + { + if (!("value" in newProps)) { + if (!hasWarnedAboutUsingNoValuePropOnContextProvider) { + hasWarnedAboutUsingNoValuePropOnContextProvider = true; - if (outerPropTypes) { - checkPropTypes( - outerPropTypes, - _resolvedProps3, // Resolved for outer only - "prop", - getComponentName(_type2) - ); - } - } + error( + "The `value` prop is required for the ``. Did you misspell it or forget to pass it?" + ); } - - _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 providerPropTypes = workInProgress.type.propTypes; + + if (providerPropTypes) { + checkPropTypes(providerPropTypes, newProps, "prop", "Context.Provider"); } + } - case IncompleteClassComponent: { - var _Component3 = workInProgress.type; - var _unresolvedProps4 = workInProgress.pendingProps; + pushProvider(workInProgress, newValue); - var _resolvedProps4 = - workInProgress.elementType === _Component3 - ? _unresolvedProps4 - : resolveDefaultProps(_Component3, _unresolvedProps4); + if (oldProps !== null) { + var oldValue = oldProps.value; + var changedBits = calculateChangedBits(context, newValue, oldValue); - return mountIncompleteClassComponent( - current, - workInProgress, - _Component3, - _resolvedProps4, - renderLanes - ); + if (changedBits === 0) { + // 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, changedBits, renderLanes); } + } - case SuspenseListComponent: { - return updateSuspenseListComponent(current, workInProgress, renderLanes); - } + var newChildren = newProps.children; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; +} - case ScopeComponent: { - break; - } +var hasWarnedAboutUsingContextAsConsumer = false; - case OffscreenComponent: { - return updateOffscreenComponent(current, workInProgress, renderLanes); +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 (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; } + } - case LegacyHiddenComponent: { - return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + 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." + ); } } + prepareToReadContext(workInProgress, renderLanes); + var newValue = readContext(context, newProps.unstable_observedBits); + var newChildren; + { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } -} + ReactCurrentOwner$1.current = workInProgress; + setIsRendering(true); + newChildren = render(newValue); + setIsRendering(false); + } // React DevTools reads this flag. -function markUpdate(workInProgress) { - // Tag the fiber with an update effect. This turns a Placement into - // a PlacementAndUpdate. - workInProgress.flags |= Update; + workInProgress.flags |= PerformedWork; + reconcileChildren(current, workInProgress, newChildren, renderLanes); + return workInProgress.child; } -function markRef$1(workInProgress) { - workInProgress.flags |= Ref; +function markWorkInProgressReceivedUpdate() { + didReceiveUpdate = true; } -var appendAllChildren; -var updateHostContainer; -var updateHostComponent$1; -var updateHostText$1; - -{ - // 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; - - 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; - } - - if (node === workInProgress) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === workInProgress) { - return; - } - - node = node.return; - } +function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { + if (current !== null) { + // Reuse previous dependencies + workInProgress.dependencies = current.dependencies; + } - node.sibling.return = node.return; - node = node.sibling; - } - }; + { + // Don't update "base" render times for bailouts. + stopProfilerTimerIfRunning(); + } - updateHostContainer = function(current, workInProgress) { - // Noop - }; + markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work. - 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; + 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; + } else { + // This fiber doesn't have work, but its subtree does. Clone the child + // fibers and continue. + cloneChildFibers(current, workInProgress); + return workInProgress.child; + } +} - 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. +function remountFiber(current, oldWorkInProgress, newWorkInProgress) { + { + var returnFiber = oldWorkInProgress.return; - 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`. + if (returnFiber === null) { + throw new Error("Cannot swap the root fiber."); + } // Disconnect from the old current. + // It will get deleted. - var updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. + current.alternate = null; + oldWorkInProgress.alternate = null; // Connect to the new tree. - 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. + newWorkInProgress.index = oldWorkInProgress.index; + newWorkInProgress.sibling = oldWorkInProgress.sibling; + newWorkInProgress.return = oldWorkInProgress.return; + newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it. - if (updatePayload) { - markUpdate(workInProgress); - } - }; + if (oldWorkInProgress === returnFiber.child) { + returnFiber.child = newWorkInProgress; + } else { + var prevSibling = returnFiber.child; - 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); - } - }; -} + if (prevSibling === null) { + throw new Error("Expected parent to have a child."); + } -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; + while (prevSibling.sibling !== oldWorkInProgress) { + prevSibling = prevSibling.sibling; - while (tailNode !== null) { - if (tailNode.alternate !== null) { - lastTailNode = tailNode; + if (prevSibling === null) { + throw new Error("Expected to find the previous sibling."); } + } - tailNode = tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + 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 (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; - } + var last = returnFiber.lastEffect; - break; + if (last !== null) { + last.nextEffect = current; + returnFiber.lastEffect = current; + } else { + returnFiber.firstEffect = returnFiber.lastEffect = current; } - 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 (_tailNode !== null) { - if (_tailNode.alternate !== null) { - _lastTailNode = _tailNode; - } + current.nextEffect = null; + current.flags = Deletion; + newWorkInProgress.flags |= Placement; // Restart work from the new fiber. - _tailNode = _tailNode.sibling; - } // Next we're simply going to delete all insertions after the - // last rendered item. + return newWorkInProgress; + } +} - 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; - } +function beginWork(current, workInProgress, renderLanes) { + var updateLanes = workInProgress.lanes; - break; + { + 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 + ) + ); } } -} -function bubbleProperties(completedWork) { - var didBailout = - completedWork.alternate !== null && - completedWork.alternate.child === completedWork.child; - var newChildLanes = NoLanes; - var subtreeFlags = NoFlags; + 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; - 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; + case HostComponent: + pushHostContext(workInProgress); + break; - 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. + case ClassComponent: { + var Component = workInProgress.type; - actualDuration += child.actualDuration; - treeBaseDuration += child.treeBaseDuration; - child = child.sibling; - } + if (isContextProvider(Component)) { + pushContextProvider(workInProgress); + } - completedWork.actualDuration = actualDuration; - completedWork.treeBaseDuration = treeBaseDuration; - } else { - var _child = completedWork.child; + break; + } - 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. + case HostPortal: + pushHostContainer( + workInProgress, + workInProgress.stateNode.containerInfo + ); + break; - _child.return = completedWork; - _child = _child.sibling; - } - } + case ContextProvider: { + var newValue = workInProgress.memoizedProps.value; + pushProvider(workInProgress, newValue); + break; + } - 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; - - 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. - - subtreeFlags |= _child2.subtreeFlags & StaticMask; - subtreeFlags |= _child2.flags & StaticMask; - _treeBaseDuration += _child2.treeBaseDuration; - _child2 = _child2.sibling; - } - - completedWork.treeBaseDuration = _treeBaseDuration; - } else { - var _child3 = completedWork.child; + case Profiler: + { + // Profiler should only call onRender when one of its descendants actually rendered. + var hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - 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 (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, - 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. + var stateNode = workInProgress.stateNode; + stateNode.effectDuration = 0; + stateNode.passiveEffectDuration = 0; + } - _child3.return = completedWork; - _child3 = _child3.sibling; - } - } + break; - completedWork.subtreeFlags |= subtreeFlags; - } + case SuspenseComponent: { + var state = workInProgress.memoizedState; - completedWork.childLanes = newChildLanes; - return didBailout; -} + 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 completeWork(current, workInProgress, renderLanes) { - var newProps = workInProgress.pendingProps; + var primaryChildFragment = workInProgress.child; + var primaryChildLanes = primaryChildFragment.childLanes; - 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 (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. - case ClassComponent: { - var Component = workInProgress.type; + var child = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes + ); - if (isContextProvider(Component)) { - popContext(workInProgress); - } + if (child !== null) { + // The fallback children have pending work. Skip over the + // primary children and work on the fallback. + return child.sibling; + } else { + return null; + } + } + } else { + pushSuspenseContext( + workInProgress, + setDefaultShallowSuspenseContext(suspenseStackCursor.current) + ); + } - bubbleProperties(workInProgress); - return null; - } + break; + } - case HostRoot: { - var fiberRoot = workInProgress.stateNode; + case SuspenseListComponent: { + var didSuspendBefore = (current.flags & DidCapture) !== NoFlags; - popHostContainer(workInProgress); - popTopLevelContextObject(workInProgress); - resetWorkInProgressVersions(); + var _hasChildWork = includesSomeLane( + renderLanes, + workInProgress.childLanes + ); - if (fiberRoot.pendingContext) { - fiberRoot.context = fiberRoot.pendingContext; - fiberRoot.pendingContext = 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. - 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(); + 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. - 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; - } - } + var renderState = workInProgress.memoizedState; - updateHostContainer(current, workInProgress); - bubbleProperties(workInProgress); - return null; - } + 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; + } - case HostComponent: { - popHostContext(workInProgress); - var rootContainerInstance = getRootHostContainer(); - var type = workInProgress.type; + pushSuspenseContext(workInProgress, suspenseStackCursor.current); - if (current !== null && workInProgress.stateNode != null) { - updateHostComponent$1( - current, - workInProgress, - type, - newProps, - rootContainerInstance - ); + 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 (current.ref !== workInProgress.ref) { - markRef$1(workInProgress); + 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); } + } + + 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 { - 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. + // 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. - bubbleProperties(workInProgress); - return null; - } + workInProgress.lanes = NoLanes; - 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. + switch (workInProgress.tag) { + case IndeterminateComponent: { + return mountIndeterminateComponent( + current, + workInProgress, + workInProgress.type, + renderLanes + ); + } - var _wasHydrated = popHydrationState(); + case LazyComponent: { + var elementType = workInProgress.elementType; + return mountLazyComponent( + current, + workInProgress, + elementType, + updateLanes, + renderLanes + ); + } - 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. + 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 (finalizeInitialChildren(instance)) { - markUpdate(workInProgress); - } - } + case ClassComponent: { + var _Component2 = workInProgress.type; + var _unresolvedProps = workInProgress.pendingProps; - if (workInProgress.ref !== null) { - // If there is a ref on a host node we need to schedule a callback - markRef$1(workInProgress); - } - } + var _resolvedProps = + workInProgress.elementType === _Component2 + ? _unresolvedProps + : resolveDefaultProps(_Component2, _unresolvedProps); - bubbleProperties(workInProgress); - return null; + return updateClassComponent( + current, + workInProgress, + _Component2, + _resolvedProps, + renderLanes + ); } - case HostText: { - var newText = newProps; + case HostRoot: + return updateHostRoot(current, workInProgress, renderLanes); - 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. + case HostComponent: + return updateHostComponent(current, workInProgress, renderLanes); - 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. - } + case HostText: + return updateHostText(); - var _rootContainerInstance = getRootHostContainer(); + case SuspenseComponent: + return updateSuspenseComponent(current, workInProgress, renderLanes); - var _currentHostContext = getHostContext(); + case HostPortal: + return updatePortalComponent(current, workInProgress, renderLanes); - var _wasHydrated2 = popHydrationState(); + case ForwardRef: { + var type = workInProgress.type; + var _unresolvedProps2 = workInProgress.pendingProps; - if (_wasHydrated2) { - if (prepareToHydrateHostTextInstance()) { - markUpdate(workInProgress); - } - } else { - workInProgress.stateNode = createTextInstance( - newText, - _rootContainerInstance, - _currentHostContext, - workInProgress - ); - } - } + var _resolvedProps2 = + workInProgress.elementType === type + ? _unresolvedProps2 + : resolveDefaultProps(type, _unresolvedProps2); - bubbleProperties(workInProgress); - return null; + return updateForwardRef( + current, + workInProgress, + type, + _resolvedProps2, + renderLanes + ); } - case SuspenseComponent: { - popSuspenseContext(workInProgress); - var nextState = workInProgress.memoizedState; - - if ((workInProgress.flags & DidCapture) !== NoFlags) { - // Something suspended. Re-render with the fallback children. - workInProgress.lanes = renderLanes; // Do not reset the effect list. + case Fragment: + return updateFragment(current, workInProgress, renderLanes); - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } // Don't bubble properties in this case. + case Mode: + return updateMode(current, workInProgress, renderLanes); - return workInProgress; - } + case Profiler: + return updateProfiler(current, workInProgress, renderLanes); - var nextDidTimeout = nextState !== null; - var prevDidTimeout = false; + case ContextProvider: + return updateContextProvider(current, workInProgress, renderLanes); - if (current === null) { - if (workInProgress.memoizedProps.fallback !== undefined); - } else { - var prevState = current.memoizedState; - prevDidTimeout = prevState !== null; - } + case ContextConsumer: + return updateContextConsumer(current, workInProgress, renderLanes); - if (nextDidTimeout && !prevDidTimeout) { - // If this subtree is running in blocking mode we can suspend, - // otherwise we won't suspend. - // 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 & BlockingMode) !== 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 MemoComponent: { + var _type2 = workInProgress.type; + var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props. - 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(); - } - } - } + var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3); { - // TODO: Only schedule updates if these values are non equal, i.e. it changed. - if (nextDidTimeout || prevDidTimeout) { - // If this boundary just timed out, schedule an effect to attach a - // retry listener to the promise. This flag is also used to hide the - // primary children. In mutation mode, we also need the flag to - // *unhide* children that were previously hidden, so check if this - // is currently timed out, too. - workInProgress.flags |= Update; - } - } - - bubbleProperties(workInProgress); + if (workInProgress.type !== workInProgress.elementType) { + var outerPropTypes = _type2.propTypes; - { - 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 doens't support type casting in combiation with the -= operator - workInProgress.treeBaseDuration -= - _primaryChildFragment2.treeBaseDuration; - } + if (outerPropTypes) { + checkPropTypes( + outerPropTypes, + _resolvedProps3, // Resolved for outer only + "prop", + getComponentName(_type2) + ); } } } - return null; + _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3); + return updateMemoComponent( + current, + workInProgress, + _type2, + _resolvedProps3, + updateLanes, + renderLanes + ); } - case HostPortal: - popHostContainer(workInProgress); - updateHostContainer(current, workInProgress); - - if (current === null) { - preparePortalMount(workInProgress.stateNode.containerInfo); - } - - bubbleProperties(workInProgress); - return null; - - case ContextProvider: - // Pop provider fiber - var context = workInProgress.type._context; - popProvider(context, workInProgress); - bubbleProperties(workInProgress); - return null; + case SimpleMemoComponent: { + return updateSimpleMemoComponent( + current, + workInProgress, + workInProgress.type, + workInProgress.pendingProps, + updateLanes, + renderLanes + ); + } 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 _Component3 = workInProgress.type; + var _unresolvedProps4 = workInProgress.pendingProps; - if (isContextProvider(_Component)) { - popContext(workInProgress); - } + var _resolvedProps4 = + workInProgress.elementType === _Component3 + ? _unresolvedProps4 + : resolveDefaultProps(_Component3, _unresolvedProps4); - bubbleProperties(workInProgress); - return null; + return mountIncompleteClassComponent( + current, + workInProgress, + _Component3, + _resolvedProps4, + renderLanes + ); } case SuspenseListComponent: { - popSuspenseContext(workInProgress); - var renderState = workInProgress.memoizedState; - - if (renderState === null) { - // We're running in the default, "independent" mode. - // We don't do anything in this mode. - bubbleProperties(workInProgress); - return null; - } - - var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; - var renderedTail = renderState.rendering; - - 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 (!cannotBeSuspended) { - var row = workInProgress.child; + return updateSuspenseListComponent(current, workInProgress, renderLanes); + } - while (row !== null) { - var suspended = findFirstSuspended(row); + case FundamentalComponent: { + break; + } - 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 ScopeComponent: { + break; + } - var newThennables = suspended.updateQueue; + case OffscreenComponent: { + return updateOffscreenComponent(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 LegacyHiddenComponent: { + return updateLegacyHiddenComponent(current, workInProgress, renderLanes); + } + } - workInProgress.subtreeFlags = NoFlags; - resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately - // rerender the children. + { + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." + ); + } +} - pushSuspenseContext( - workInProgress, - setShallowSuspenseContext( - suspenseStackCursor.current, - ForceSuspenseFallback - ) - ); // Don't bubble properties in this case. +function markUpdate(workInProgress) { + // Tag the fiber with an update effect. This turns a Placement into + // a PlacementAndUpdate. + workInProgress.flags |= Update; +} - return workInProgress.child; - } +function markRef$1(workInProgress) { + workInProgress.flags |= Ref; +} - row = row.sibling; - } - } +var appendAllChildren; +var updateHostContainer; +var updateHostComponent$1; +var updateHostText$1; - 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. +{ + // 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; - workInProgress.lanes = SomeRetryLane; + 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; + } - { - markSpawnedWork(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); + if (node === workInProgress) { + return; + } - 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. + while (node.sibling === null) { + if (node.return === null || node.return === workInProgress) { + return; + } - var _newThennables = _suspended.updateQueue; + node = node.return; + } - if (_newThennables !== null) { - workInProgress.updateQueue = _newThennables; - workInProgress.flags |= Update; - } + node.sibling.return = node.return; + node = node.sibling; + } + }; - cutOffTailIfNeeded(renderState, true); // This might have been modified. + updateHostContainer = function(workInProgress) { + // Noop + }; - 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. + 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; - workInProgress.lanes = SomeRetryLane; + 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. - { - markSpawnedWork(SomeRetryLane); - } - } - } + 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`. - 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 updatePayload = prepareUpdate(); // TODO: Type this specific to this type of component. - if (previousSibling !== null) { - previousSibling.sibling = renderedTail; - } else { - workInProgress.child = renderedTail; - } + 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. - renderState.last = renderedTail; - } - } + if (updatePayload) { + markUpdate(workInProgress); + } + }; - 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. + 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); + } + }; +} - var suspenseContext = suspenseStackCursor.current; +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 (didSuspendAlready) { - suspenseContext = setShallowSuspenseContext( - suspenseContext, - ForceSuspenseFallback - ); - } else { - suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); + while (tailNode !== null) { + if (tailNode.alternate !== null) { + lastTailNode = tailNode; } - pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. - // Don't bubble properties in this case. + tailNode = tailNode.sibling; + } // Next we're simply going to delete all insertions after the + // last rendered item. - return next; + 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; } - bubbleProperties(workInProgress); - return null; - } - - 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; + 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 ( - prevIsHidden !== nextIsHidden && - newProps.mode !== "unstable-defer-without-hiding" - ) { - workInProgress.flags |= Update; + while (_tailNode !== null) { + if (_tailNode.alternate !== null) { + _lastTailNode = _tailNode; } - } // Don't bubble properties for hidden children. - if ( - !nextIsHidden || - includesSomeLane(subtreeRenderLanes, OffscreenLane) || - (workInProgress.mode & ConcurrentMode) === NoMode - ) { - bubbleProperties(workInProgress); + _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; } - return null; + break; } } - - { - throw Error( - "Unknown unit of work tag (" + - workInProgress.tag + - "). This error is likely caused by a bug in React. Please file an issue." - ); - } } -function unwindWork(workInProgress, renderLanes) { +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: + return null; + case ClassComponent: { var Component = workInProgress.type; @@ -16284,18 +15293,6 @@ function unwindWork(workInProgress, renderLanes) { popContext(workInProgress); } - var flags = workInProgress.flags; - - if (flags & ShouldCapture) { - workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; - - if ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); - } - - return workInProgress; - } - return null; } @@ -16303,2393 +15300,2330 @@ function unwindWork(workInProgress, renderLanes) { popHostContainer(workInProgress); popTopLevelContextObject(workInProgress); resetWorkInProgressVersions(); - var _flags = workInProgress.flags; + var fiberRoot = workInProgress.stateNode; - if (!((_flags & DidCapture) === NoFlags)) { - throw Error( - "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." - ); + if (fiberRoot.pendingContext) { + fiberRoot.context = fiberRoot.pendingContext; + fiberRoot.pendingContext = null; } - workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; - return workInProgress; - } - - case HostComponent: { - // TODO: popHydrationState - popHostContext(workInProgress); - return null; - } - - case SuspenseComponent: { - popSuspenseContext(workInProgress); - - var _flags2 = workInProgress.flags; - - if (_flags2 & ShouldCapture) { - workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + 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 ((workInProgress.mode & ProfileMode) !== NoMode) { - transferActualDuration(workInProgress); + 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; } - - return workInProgress; } + updateHostContainer(workInProgress); return null; } - case SuspenseListComponent: { - popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been - // caught by a nested boundary. If not, it should bubble through. - - return null; - } - - case HostPortal: - popHostContainer(workInProgress); - return null; - - case ContextProvider: - var context = workInProgress.type._context; - popProvider(context, workInProgress); - return null; - - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(workInProgress); - - return null; - - case CacheComponent: - return null; + case HostComponent: { + popHostContext(workInProgress); + var rootContainerInstance = getRootHostContainer(); + var type = workInProgress.type; - default: - return null; - } -} + if (current !== null && workInProgress.stateNode != null) { + updateHostComponent$1( + current, + workInProgress, + type, + newProps, + rootContainerInstance + ); -function unwindInterruptedWork(interruptedWork, renderLanes) { - switch (interruptedWork.tag) { - case ClassComponent: { - var childContextTypes = interruptedWork.type.childContextTypes; + 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 (childContextTypes !== null && childContextTypes !== undefined) { - popContext(interruptedWork); - } + return null; + } - break; - } + 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. - case HostRoot: { - popHostContainer(interruptedWork); - popTopLevelContextObject(interruptedWork); - resetWorkInProgressVersions(); - break; - } + var _wasHydrated = popHydrationState(); - case HostComponent: { - popHostContext(interruptedWork); - break; - } + 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. - case HostPortal: - popHostContainer(interruptedWork); - break; + if (finalizeInitialChildren(instance)) { + markUpdate(workInProgress); + } + } - case SuspenseComponent: - popSuspenseContext(interruptedWork); - break; + if (workInProgress.ref !== null) { + // If there is a ref on a host node we need to schedule a callback + markRef$1(workInProgress); + } + } - case SuspenseListComponent: - popSuspenseContext(interruptedWork); - break; + return null; + } - case ContextProvider: - var context = interruptedWork.type._context; - popProvider(context, interruptedWork); - break; + case HostText: { + var newText = newProps; - case OffscreenComponent: - case LegacyHiddenComponent: - popRenderLanes(interruptedWork); + 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. - break; - } -} + 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. + } -function createCapturedValue(value, source) { - // If the value is an error, call this function immediately after it is thrown - // so the stack is accurate. - return { - value: value, - source: source, - stack: getStackByFiberInDevAndProd(source) - }; -} + var _rootContainerInstance = getRootHostContainer(); -if ( - !( - typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === - "function" - ) -) { - throw Error( - "Expected ReactFiberErrorDialog.showErrorDialog to be a function." - ); -} + var _currentHostContext = getHostContext(); -function showErrorDialog(boundary, errorInfo) { - var capturedError = { - componentStack: errorInfo.stack !== null ? errorInfo.stack : "", - error: errorInfo.value, - errorBoundary: - boundary !== null && boundary.tag === ClassComponent - ? boundary.stateNode - : null - }; - return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( - capturedError - ); -} + var _wasHydrated2 = popHydrationState(); -function logCapturedError(boundary, errorInfo) { - try { - var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. - // This enables renderers like ReactNative to better manage redbox behavior. + if (_wasHydrated2) { + if (prepareToHydrateHostTextInstance()) { + markUpdate(workInProgress); + } + } else { + workInProgress.stateNode = createTextInstance( + newText, + _rootContainerInstance, + _currentHostContext, + workInProgress + ); + } + } - if (logError === false) { - return; + return null; } - var error = errorInfo.value; + case SuspenseComponent: { + popSuspenseContext(workInProgress); + var nextState = workInProgress.memoizedState; - if (true) { - var source = errorInfo.source; - var stack = errorInfo.stack; - var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling - // `preventDefault()` in window `error` handler. - // We record this information as an expando on the error. + if ((workInProgress.flags & DidCapture) !== NoFlags) { + // Something suspended. Re-render with the fallback children. + workInProgress.lanes = renderLanes; // Do not reset the effect list. - if (error != null && error._suppressLogging) { - if (boundary.tag === ClassComponent) { - // The error is recoverable and was silenced. - // Ignore it and don't print the stack addendum. - // This is handy for testing error boundaries without noise. - return; - } // The error is fatal. Since the silencing might have - // been accidental, we'll surface it anyway. - // However, the browser would have silenced the original error - // so we'll print it first, and then print the stack addendum. + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } - console["error"](error); // Don't transform to our wrapper - // For a more detailed description of this block, see: - // https://github.com/facebook/react/pull/13384 + return workInProgress; } - var componentName = source ? getComponentName(source.type) : null; - var componentNameMessage = componentName - ? "The above error occurred in the <" + componentName + "> component:" - : "The above error occurred in one of your React components:"; - var errorBoundaryMessage; - var errorBoundaryName = getComponentName(boundary.type); + var nextDidTimeout = nextState !== null; + var prevDidTimeout = false; - if (errorBoundaryName) { - errorBoundaryMessage = - "React will try to recreate this component tree from scratch " + - ("using the error boundary you provided, " + errorBoundaryName + "."); + if (current === null) { + if (workInProgress.memoizedProps.fallback !== undefined); } else { - errorBoundaryMessage = - "Consider adding an error boundary to your tree to customize error handling behavior.\n" + - "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; + var prevState = current.memoizedState; + prevDidTimeout = prevState !== null; } - var combinedMessage = - componentNameMessage + - "\n" + - componentStack + - "\n\n" + - ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. - // We don't include the original error message and JS stack because the browser - // has already printed it. Even if the application swallows the error, it is still - // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - - console["error"](combinedMessage); // Don't transform to our wrapper - } else { - // In production, we print the error directly. - // This will include the message, the JS stack, and anything the browser wants to show. - // We pass the error object instead of custom message so that the browser displays the error natively. - console["error"](error); // Don't transform to our wrapper - } - } catch (e) { - // This method must not throw, or React internal state will get messed up. - // If console.error is overridden, or logCapturedError() shows a dialog that throws, - // we want to report this error outside of the normal stack as a last resort. - // https://github.com/facebook/react/issues/13188 - setTimeout(function() { - throw e; - }); - } -} - -var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; - -function createRootErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - - update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property - // being called "element". - - update.payload = { - element: null - }; - var error = errorInfo.value; + if (nextDidTimeout && !prevDidTimeout) { + // If this subtreee is running in blocking mode we can suspend, + // otherwise we won't suspend. + // 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 & BlockingMode) !== 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; - update.callback = function() { - onUncaughtError(error); - logCapturedError(fiber, errorInfo); - }; + 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(); + } + } + } - return update; -} + { + // TODO: Only schedule updates if these values are non equal, i.e. it changed. + if (nextDidTimeout || prevDidTimeout) { + // If this boundary just timed out, schedule an effect to attach a + // retry listener to the promise. This flag is also used to hide the + // primary children. In mutation mode, we also need the flag to + // *unhide* children that were previously hidden, so check if this + // is currently timed out, too. + workInProgress.flags |= Update; + } + } -function createClassErrorUpdate(fiber, errorInfo, lane) { - var update = createUpdate(NoTimestamp, lane); - update.tag = CaptureUpdate; - var getDerivedStateFromError = fiber.type.getDerivedStateFromError; + return null; + } - if (typeof getDerivedStateFromError === "function") { - var error$1 = errorInfo.value; + case HostPortal: + popHostContainer(workInProgress); + updateHostContainer(workInProgress); - update.payload = function() { - logCapturedError(fiber, errorInfo); - return getDerivedStateFromError(error$1); - }; - } + if (current === null) { + preparePortalMount(workInProgress.stateNode.containerInfo); + } - var inst = fiber.stateNode; + return null; - if (inst !== null && typeof inst.componentDidCatch === "function") { - update.callback = function callback() { - { - markFailedErrorBoundaryForHotReloading(fiber); - } + case ContextProvider: + // Pop provider fiber + popProvider(workInProgress); + return null; - if (typeof getDerivedStateFromError !== "function") { - // To preserve the preexisting retry behavior of error boundaries, - // we keep track of which ones already failed during this batch. - // This gets reset before we yield back to the browser. - // TODO: Warn in strict mode if getDerivedStateFromError is - // not defined. - markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + 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; - logCapturedError(fiber, errorInfo); + if (isContextProvider(_Component)) { + popContext(workInProgress); } - var error$1 = errorInfo.value; - var stack = errorInfo.stack; - this.componentDidCatch(error$1, { - componentStack: stack !== null ? stack : "" - }); + return null; + } - { - if (typeof getDerivedStateFromError !== "function") { - // If componentDidCatch is the only error boundary method defined, - // then it needs to call setState to recover from errors. - // If no state update is scheduled then the boundary will swallow the error. - if (!includesSomeLane(fiber.lanes, SyncLane)) { - error( - "%s: Error boundaries should implement getDerivedStateFromError(). " + - "In that method, return a state update to display an error message or fallback UI.", - getComponentName(fiber.type) || "Unknown" - ); - } - } + case SuspenseListComponent: { + popSuspenseContext(workInProgress); + var renderState = workInProgress.memoizedState; + + if (renderState === null) { + // We're running in the default, "independent" mode. + // We don't do anything in this mode. + return null; } - }; - } else { - update.callback = function() { - markFailedErrorBoundaryForHotReloading(fiber); - }; - } - return update; -} + var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags; + var renderedTail = renderState.rendering; -function attachPingListener(root, wakeable, lanes) { - // Attach a listener to the promise to "ping" the root and retry. But only if - // one does not already exist for the lanes we're currently rendering (which - // acts like a "thread ID" here). - var pingCache = root.pingCache; - var threadIDs; + 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 (pingCache === null) { - pingCache = root.pingCache = new PossiblyWeakMap$1(); - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } else { - threadIDs = pingCache.get(wakeable); + if (!cannotBeSuspended) { + var row = workInProgress.child; - if (threadIDs === undefined) { - threadIDs = new Set(); - pingCache.set(wakeable, threadIDs); - } - } + while (row !== null) { + var suspended = findFirstSuspended(row); - if (!threadIDs.has(lanes)) { - // Memoize using the thread ID to prevent redundant listeners. - threadIDs.add(lanes); - var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); - wakeable.then(ping, ping); - } -} + 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. -function throwException( - root, - returnFiber, - sourceFiber, - value, - rootRenderLanes -) { - // The source fiber did not complete. - sourceFiber.flags |= Incomplete; + var newThennables = suspended.updateQueue; - if ( - value !== null && - typeof value === "object" && - typeof value.then === "function" - ) { - // This is a wakeable. - var wakeable = value; - // A legacy mode Suspense quirk, only relevant to hook components. + 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 list before doing the second pass since that's now invalid. - var tag = sourceFiber.tag; + if (renderState.lastEffect === null) { + workInProgress.firstEffect = null; + } - if ( - (sourceFiber.mode & BlockingMode) === NoMode && - (tag === FunctionComponent || - tag === ForwardRef || - tag === SimpleMemoComponent) - ) { - var currentSource = sourceFiber.alternate; + workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state. - if (currentSource) { - sourceFiber.updateQueue = currentSource.updateQueue; - sourceFiber.memoizedState = currentSource.memoizedState; - sourceFiber.lanes = currentSource.lanes; - } else { - sourceFiber.updateQueue = null; - sourceFiber.memoizedState = null; - } - } + resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately + // rerender the children. - var hasInvisibleParentBoundary = hasSuspenseContext( - suspenseStackCursor.current, - InvisibleParentSuspenseContext - ); // Schedule the nearest Suspense to re-render the timed out view. + pushSuspenseContext( + workInProgress, + setShallowSuspenseContext( + suspenseStackCursor.current, + ForceSuspenseFallback + ) + ); + return workInProgress.child; + } - var _workInProgress = returnFiber; + row = row.sibling; + } + } - do { - if ( - _workInProgress.tag === SuspenseComponent && - shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) - ) { - // Found the nearest boundary. - // Stash the promise on the boundary fiber. If the boundary times out, we'll - // attach another listener to flip the boundary back to its normal state. - var wakeables = _workInProgress.updateQueue; + 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. - if (wakeables === null) { - var updateQueue = new Set(); - updateQueue.add(wakeable); - _workInProgress.updateQueue = updateQueue; - } else { - wakeables.add(wakeable); - } // If the boundary is outside of blocking mode, we should *not* - // suspend the commit. Pretend as if the suspended component rendered - // null and keep rendering. In the commit phase, we'll schedule a - // subsequent synchronous update to re-render the Suspense. - // - // Note: It doesn't matter whether the component that suspended was - // inside a blocking mode tree. If the Suspense is outside of it, we - // should *not* suspend the commit. - // - // If the suspense boundary suspended itself suspended, we don't have to - // do this trick because nothing was partially started. We can just - // directly do a second pass over the fallback in this render and - // pretend we meant to render that directly. + workInProgress.lanes = SomeRetryLane; - if ( - (_workInProgress.mode & BlockingMode) === NoMode && - _workInProgress !== returnFiber - ) { - _workInProgress.flags |= DidCapture; - sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. - // But we shouldn't call any lifecycle methods or callbacks. Remove - // all lifecycle effect tags. + { + markSpawnedWork(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); - sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); + 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 (sourceFiber.tag === ClassComponent) { - var currentSourceFiber = sourceFiber.alternate; + var _newThennables = _suspended.updateQueue; - if (currentSourceFiber === null) { - // This is a new mount. Change the tag so it's not mistaken for a - // completed class component. For example, we should not call - // componentWillUnmount if it is deleted. - sourceFiber.tag = IncompleteClassComponent; - } else { - // When we try rendering again, we should not reuse the current fiber, - // since it's known to be in an inconsistent state. Use a force update to - // prevent a bail out. - var update = createUpdate(NoTimestamp, SyncLane); - update.tag = ForceUpdate; - enqueueUpdate(sourceFiber, update); + if (_newThennables !== null) { + workInProgress.updateQueue = _newThennables; + workInProgress.flags |= Update; } - } // The source fiber did not complete. Mark it with Sync priority to - // indicate that it still has pending work. - sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. + cutOffTailIfNeeded(renderState, true); // This might have been modified. - return; - } // Confirmed that the boundary is in a concurrent mode tree. Continue - // with the normal suspend path. - // - // After this we'll use a set of heuristics to determine whether this - // render pass will run to completion or restart or "suspend" the commit. - // The actual logic for this is spread out in different places. - // - // This first principle is that if we're going to suspend when we complete - // a root, then we should also restart if we get an update or ping that - // might unsuspend it, and vice versa. The only reason to suspend is - // because you think you might want to restart before committing. However, - // it doesn't make sense to restart only while in the period we're suspended. - // - // Restarting too aggressively is also not good because it starves out any - // intermediate loading state. So we use heuristics to determine when. - // Suspense Heuristics - // - // If nothing threw a Promise or all the same fallbacks are already showing, - // then don't suspend/restart. - // - // If this is an initial render of a new tree of Suspense boundaries and - // those trigger a fallback, then don't suspend/restart. We want to ensure - // that we can show the initial loading state as quickly as possible. - // - // If we hit a "Delayed" case, such as when we'd switch from content back into - // a fallback, then we should always suspend/restart. Transitions apply - // to this case. If none is defined, JND is used instead. - // - // If we're already showing a fallback and it gets "retried", allowing us to show - // another level, but there's still an inner boundary that would show a fallback, - // then we suspend/restart for 500ms since the last time we showed a fallback - // anywhere in the tree. This effectively throttles progressive loading into a - // consistent train of commits. This also gives us an opportunity to restart to - // get to the completed state slightly earlier. - // - // If there's ambiguity due to batching it's resolved in preference of: - // 1) "delayed", 2) "initial render", 3) "retry". - // - // We want to ensure that a "busy" state doesn't get force committed. We want to - // ensure that new initial loading states can commit as soon as possible. + if ( + renderState.tail === null && + renderState.tailMode === "hidden" && + !renderedTail.alternate && + !getIsHydrating() // We don't cut it if we're hydrating. + ) { + // We need to delete the row we just rendered. + // Reset the effect list to what it was before we rendered this + // child. The nested children have already appended themselves. + var lastEffect = (workInProgress.lastEffect = + renderState.lastEffect); // Remove any effects that were appended after this point. - attachPingListener(root, wakeable, rootRenderLanes); - _workInProgress.flags |= ShouldCapture; - _workInProgress.lanes = rootRenderLanes; - return; - } // This boundary already captured during this render. Continue to the next - // boundary. + if (lastEffect !== null) { + lastEffect.nextEffect = null; + } // We're done. - _workInProgress = _workInProgress.return; - } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. - // TODO: Use invariant so the message is stripped in prod? + 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. - value = new Error( - (getComponentName(sourceFiber.type) || "A React component") + - " suspended while rendering, but no fallback UI was specified.\n" + - "\n" + - "Add a component higher in the tree to " + - "provide a loading indicator or placeholder to display." - ); - } // We didn't find a boundary that could handle this type of exception. Start - // over and traverse parent path again, this time treating the exception - // as an error. + workInProgress.lanes = SomeRetryLane; - renderDidError(); - value = createCapturedValue(value, sourceFiber); - var workInProgress = returnFiber; + { + markSpawnedWork(SomeRetryLane); + } + } + } - do { - switch (workInProgress.tag) { - case HostRoot: { - var _errorInfo = value; - workInProgress.flags |= ShouldCapture; - var lane = pickArbitraryLane(rootRenderLanes); - workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); + 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 _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); + if (previousSibling !== null) { + previousSibling.sibling = renderedTail; + } else { + workInProgress.child = renderedTail; + } - enqueueCapturedUpdate(workInProgress, _update); - return; + renderState.last = renderedTail; + } } - case ClassComponent: - // Capture and retry - var errorInfo = value; - var ctor = workInProgress.type; - var instance = workInProgress.stateNode; - - if ( - (workInProgress.flags & DidCapture) === NoFlags && - (typeof ctor.getDerivedStateFromError === "function" || - (instance !== null && - typeof instance.componentDidCatch === "function" && - !isAlreadyFailedLegacyErrorBoundary(instance))) - ) { - workInProgress.flags |= ShouldCapture; - - var _lane = pickArbitraryLane(rootRenderLanes); + 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.lastEffect = workInProgress.lastEffect; + 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.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state + var suspenseContext = suspenseStackCursor.current; - var _update2 = createClassErrorUpdate( - workInProgress, - errorInfo, - _lane + if (didSuspendAlready) { + suspenseContext = setShallowSuspenseContext( + suspenseContext, + ForceSuspenseFallback ); - - enqueueCapturedUpdate(workInProgress, _update2); - return; + } else { + suspenseContext = setDefaultShallowSuspenseContext(suspenseContext); } - break; + pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row. + + return next; + } + + return null; } - workInProgress = workInProgress.return; - } while (workInProgress !== null); -} + case FundamentalComponent: { + break; + } -var didWarnAboutUndefinedSnapshotBeforeUpdate = null; + case ScopeComponent: { + break; + } -{ - didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); -} + case OffscreenComponent: + case LegacyHiddenComponent: { + popRenderLanes(workInProgress); -var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; -var nextEffect = null; + if (current !== null) { + var _nextState = workInProgress.memoizedState; + var _prevState = current.memoizedState; + var prevIsHidden = _prevState !== null; + var nextIsHidden = _nextState !== null; -var callComponentWillUnmountWithTimer = function(current, instance) { - instance.props = current.memoizedProps; - instance.state = current.memoizedState; + if ( + prevIsHidden !== nextIsHidden && + newProps.mode !== "unstable-defer-without-hiding" + ) { + workInProgress.flags |= Update; + } + } - { - instance.componentWillUnmount(); + return null; + } } -}; // Capture errors so they don't interrupt unmounting. -function safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance -) { { - invokeGuardedCallback( - null, - callComponentWillUnmountWithTimer, - null, - current, - instance + throw Error( + "Unknown unit of work tag (" + + workInProgress.tag + + "). This error is likely caused by a bug in React. Please file an issue." ); - - if (hasCaughtError()) { - var unmountError = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, unmountError); - } } } -function safelyDetachRef(current, nearestMountedAncestor) { - var ref = current.ref; +function unwindWork(workInProgress, renderLanes) { + switch (workInProgress.tag) { + case ClassComponent: { + var Component = workInProgress.type; - if (ref !== null) { - if (typeof ref === "function") { - { - { - invokeGuardedCallback(null, ref, null, null); - } + if (isContextProvider(Component)) { + popContext(workInProgress); + } - if (hasCaughtError()) { - var refError = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, refError); + var flags = workInProgress.flags; + + if (flags & ShouldCapture) { + workInProgress.flags = (flags & ~ShouldCapture) | DidCapture; + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); } + + return workInProgress; } - } else { - ref.current = null; + + return null; } - } -} -function safelyCallDestroy(current, nearestMountedAncestor, destroy) { - { - invokeGuardedCallback(null, destroy, null); + case HostRoot: { + popHostContainer(workInProgress); + popTopLevelContextObject(workInProgress); + resetWorkInProgressVersions(); + var _flags = workInProgress.flags; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(current, nearestMountedAncestor, error); + if (!((_flags & DidCapture) === NoFlags)) { + throw Error( + "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." + ); + } + + workInProgress.flags = (_flags & ~ShouldCapture) | DidCapture; + return workInProgress; } - } -} -var focusedInstanceHandle = null; -var shouldFireAfterActiveInstanceBlur = false; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = prepareForCommit(root.containerInfo); - nextEffect = firstChild; - commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber + case HostComponent: { + // TODO: popHydrationState + popHostContext(workInProgress); + return null; + } - var shouldFire = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = false; - focusedInstanceHandle = null; - return shouldFire; -} + case SuspenseComponent: { + popSuspenseContext(workInProgress); -function commitBeforeMutationEffects_begin() { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization + var _flags2 = workInProgress.flags; - var deletions = fiber.deletions; + if (_flags2 & ShouldCapture) { + workInProgress.flags = (_flags2 & ~ShouldCapture) | DidCapture; // Captured a suspense effect. Re-render the boundary. + + if ((workInProgress.mode & ProfileMode) !== NoMode) { + transferActualDuration(workInProgress); + } - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var deletion = deletions[i]; - commitBeforeMutationEffectsDeletion(deletion); + return workInProgress; } + + return null; } - var child = fiber.child; + case SuspenseListComponent: { + popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been + // caught by a nested boundary. If not, it should bubble through. - if ( - (fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && - child !== null - ) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitBeforeMutationEffects_complete(); + return null; } + + case HostPortal: + popHostContainer(workInProgress); + return null; + + case ContextProvider: + popProvider(workInProgress); + return null; + + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(workInProgress); + return null; + + default: + return null; } } -function commitBeforeMutationEffects_complete() { - while (nextEffect !== null) { - var fiber = nextEffect; - - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitBeforeMutationEffectsOnFiber, - null, - fiber - ); +function unwindInterruptedWork(interruptedWork) { + switch (interruptedWork.tag) { + case ClassComponent: { + var childContextTypes = interruptedWork.type.childContextTypes; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); + if (childContextTypes !== null && childContextTypes !== undefined) { + popContext(interruptedWork); } - resetCurrentFiber(); + break; } - var sibling = fiber.sibling; + case HostRoot: { + popHostContainer(interruptedWork); + popTopLevelContextObject(interruptedWork); + resetWorkInProgressVersions(); + break; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; + case HostComponent: { + popHostContext(interruptedWork); + break; } - nextEffect = fiber.return; - } -} + case HostPortal: + popHostContainer(interruptedWork); + break; -function commitBeforeMutationEffectsOnFiber(finishedWork) { - var current = finishedWork.alternate; - var flags = finishedWork.flags; + case SuspenseComponent: + popSuspenseContext(interruptedWork); + break; - if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { - // Check to see if the focused element was inside of a hidden (Suspense) subtree. - // TODO: Move this out of the hot path using a dedicated effect tag. - if ( - finishedWork.tag === SuspenseComponent && - isSuspenseBoundaryBeingHidden(current, finishedWork) && - doesFiberContain(finishedWork, focusedInstanceHandle) - ) { - shouldFireAfterActiveInstanceBlur = true; - } - } + case SuspenseListComponent: + popSuspenseContext(interruptedWork); + break; - if ((flags & Snapshot) !== NoFlags) { - setCurrentFiber(finishedWork); + case ContextProvider: + popProvider(interruptedWork); + break; - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - break; - } + case OffscreenComponent: + case LegacyHiddenComponent: + popRenderLanes(interruptedWork); + break; + } +} - case ClassComponent: { - if (current !== null) { - var prevProps = current.memoizedProps; - var prevState = current.memoizedState; - var instance = finishedWork.stateNode; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. +function createCapturedValue(value, source) { + // If the value is an error, call this function immediately after it is thrown + // so the stack is accurate. + return { + value: value, + source: source, + stack: getStackByFiberInDevAndProd(source) + }; +} - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } +if ( + !( + typeof ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog === + "function" + ) +) { + throw Error( + "Expected ReactFiberErrorDialog.showErrorDialog to be a function." + ); +} - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "getSnapshotBeforeUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } +function showErrorDialog(boundary, errorInfo) { + var capturedError = { + componentStack: errorInfo.stack !== null ? errorInfo.stack : "", + error: errorInfo.value, + errorBoundary: + boundary !== null && boundary.tag === ClassComponent + ? boundary.stateNode + : null + }; + return ReactNativePrivateInterface.ReactFiberErrorDialog.showErrorDialog( + capturedError + ); +} - var snapshot = instance.getSnapshotBeforeUpdate( - finishedWork.elementType === finishedWork.type - ? prevProps - : resolveDefaultProps(finishedWork.type, prevProps), - prevState - ); +function logCapturedError(boundary, errorInfo) { + try { + var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging. + // This enables renderers like ReactNative to better manage redbox behavior. - { - var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; + if (logError === false) { + return; + } - if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { - didWarnSet.add(finishedWork.type); + var error = errorInfo.value; - error( - "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + - "must be returned. You have returned undefined.", - getComponentName(finishedWork.type) - ); - } - } + if (true) { + var source = errorInfo.source; + var stack = errorInfo.stack; + var componentStack = stack !== null ? stack : ""; // Browsers support silencing uncaught errors by calling + // `preventDefault()` in window `error` handler. + // We record this information as an expando on the error. - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } + if (error != null && error._suppressLogging) { + if (boundary.tag === ClassComponent) { + // The error is recoverable and was silenced. + // Ignore it and don't print the stack addendum. + // This is handy for testing error boundaries without noise. + return; + } // The error is fatal. Since the silencing might have + // been accidental, we'll surface it anyway. + // However, the browser would have silenced the original error + // so we'll print it first, and then print the stack addendum. - break; + console["error"](error); // Don't transform to our wrapper + // For a more detailed description of this block, see: + // https://github.com/facebook/react/pull/13384 } - case HostRoot: { - { - var root = finishedWork.stateNode; - clearContainer(root.containerInfo); - } + var componentName = source ? getComponentName(source.type) : null; + var componentNameMessage = componentName + ? "The above error occurred in the <" + componentName + "> component:" + : "The above error occurred in one of your React components:"; + var errorBoundaryMessage; + var errorBoundaryName = getComponentName(boundary.type); - break; + if (errorBoundaryName) { + errorBoundaryMessage = + "React will try to recreate this component tree from scratch " + + ("using the error boundary you provided, " + errorBoundaryName + "."); + } else { + errorBoundaryMessage = + "Consider adding an error boundary to your tree to customize error handling behavior.\n" + + "Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries."; } - case HostComponent: - case HostText: - case HostPortal: - case IncompleteClassComponent: - // Nothing to do for these component types - break; + var combinedMessage = + componentNameMessage + + "\n" + + componentStack + + "\n\n" + + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack. + // We don't include the original error message and JS stack because the browser + // has already printed it. Even if the application swallows the error, it is still + // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils. - default: { - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } + console["error"](combinedMessage); // Don't transform to our wrapper + } else { + // In production, we print the error directly. + // This will include the message, the JS stack, and anything the browser wants to show. + // We pass the error object instead of custom message so that the browser displays the error natively. + console["error"](error); // Don't transform to our wrapper } - - resetCurrentFiber(); + } catch (e) { + // This method must not throw, or React internal state will get messed up. + // If console.error is overridden, or logCapturedError() shows a dialog that throws, + // we want to report this error outside of the normal stack as a last resort. + // https://github.com/facebook/react/issues/13188 + setTimeout(function() { + throw e; + }); } } -function commitBeforeMutationEffectsDeletion(deletion) { - // TODO (effects) It would be nice to avoid calling doesFiberContain() - // Maybe we can repurpose one of the subtreeFlags positions for this instead? - // Use it to store which part of the tree the focused instance is in? - // This assumes we can safely determine that instance during the "render" phase. - if (doesFiberContain(deletion, focusedInstanceHandle)) { - shouldFireAfterActiveInstanceBlur = true; - } -} +var PossiblyWeakMap$1 = typeof WeakMap === "function" ? WeakMap : Map; -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor -) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function createRootErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null. - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property + // being called "element". - do { - if ((effect.tag & flags) === flags) { - // Unmount - var destroy = effect.destroy; - effect.destroy = undefined; + update.payload = { + element: null + }; + var error = errorInfo.value; - if (destroy !== undefined) { - safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy); - } - } + update.callback = function() { + onUncaughtError(error); + logCapturedError(fiber, errorInfo); + }; - effect = effect.next; - } while (effect !== firstEffect); - } + return update; } -function commitHookEffectListMount(tag, finishedWork) { - var updateQueue = finishedWork.updateQueue; - var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; +function createClassErrorUpdate(fiber, errorInfo, lane) { + var update = createUpdate(NoTimestamp, lane); + update.tag = CaptureUpdate; + var getDerivedStateFromError = fiber.type.getDerivedStateFromError; - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + if (typeof getDerivedStateFromError === "function") { + var error$1 = errorInfo.value; - do { - if ((effect.tag & tag) === tag) { - // Mount - var create = effect.create; - effect.destroy = create(); + update.payload = function() { + logCapturedError(fiber, errorInfo); + return getDerivedStateFromError(error$1); + }; + } - { - var destroy = effect.destroy; + var inst = fiber.stateNode; - if (destroy !== undefined && typeof destroy !== "function") { - var addendum = void 0; + if (inst !== null && typeof inst.componentDidCatch === "function") { + update.callback = function callback() { + { + markFailedErrorBoundaryForHotReloading(fiber); + } - if (destroy === null) { - addendum = - " You returned null. If your effect does not require clean " + - "up, return undefined (or nothing)."; - } else if (typeof destroy.then === "function") { - addendum = - "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + - "Instead, write the async function inside your effect " + - "and call it immediately:\n\n" + - "useEffect(() => {\n" + - " async function fetchData() {\n" + - " // You can await here\n" + - " const response = await MyAPI.getData(someId);\n" + - " // ...\n" + - " }\n" + - " fetchData();\n" + - "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + - "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; - } else { - addendum = " You returned: " + destroy; - } + if (typeof getDerivedStateFromError !== "function") { + // To preserve the preexisting retry behavior of error boundaries, + // we keep track of which ones already failed during this batch. + // This gets reset before we yield back to the browser. + // TODO: Warn in strict mode if getDerivedStateFromError is + // not defined. + markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined + + logCapturedError(fiber, errorInfo); + } + + var error$1 = errorInfo.value; + var stack = errorInfo.stack; + this.componentDidCatch(error$1, { + componentStack: stack !== null ? stack : "" + }); + { + if (typeof getDerivedStateFromError !== "function") { + // If componentDidCatch is the only error boundary method defined, + // then it needs to call setState to recover from errors. + // If no state update is scheduled then the boundary will swallow the error. + if (!includesSomeLane(fiber.lanes, SyncLane)) { error( - "An effect function must not return anything besides a function, " + - "which is used for clean-up.%s", - addendum + "%s: Error boundaries should implement getDerivedStateFromError(). " + + "In that method, return a state update to display an error message or fallback UI.", + getComponentName(fiber.type) || "Unknown" ); } } } + }; + } else { + update.callback = function() { + markFailedErrorBoundaryForHotReloading(fiber); + }; + } - effect = effect.next; - } while (effect !== firstEffect); + return update; +} + +function attachPingListener(root, wakeable, lanes) { + // Attach a listener to the promise to "ping" the root and retry. But only if + // one does not already exist for the lanes we're currently rendering (which + // acts like a "thread ID" here). + var pingCache = root.pingCache; + var threadIDs; + + if (pingCache === null) { + pingCache = root.pingCache = new PossiblyWeakMap$1(); + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } else { + threadIDs = pingCache.get(wakeable); + + if (threadIDs === undefined) { + threadIDs = new Set(); + pingCache.set(wakeable, threadIDs); + } + } + + if (!threadIDs.has(lanes)) { + // Memoize using the thread ID to prevent redundant listeners. + threadIDs.add(lanes); + var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes); + wakeable.then(ping, ping); } } -function commitLayoutEffectOnFiber( - finishedRoot, - current, - finishedWork, - committedLanes +function throwException( + root, + returnFiber, + sourceFiber, + value, + rootRenderLanes ) { - if ((finishedWork.flags & (Update | Callback)) !== NoFlags) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - // At this point layout effects have already been destroyed (during mutation phase). - // This is done to prevent sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. - { - commitHookEffectListMount(Layout | HasEffect, finishedWork); - } + // The source fiber did not complete. + sourceFiber.flags |= Incomplete; // Its effect list is no longer valid. - break; + sourceFiber.firstEffect = sourceFiber.lastEffect = null; + + if ( + value !== null && + typeof value === "object" && + typeof value.then === "function" + ) { + // This is a wakeable. + var wakeable = value; + + if ((sourceFiber.mode & BlockingMode) === NoMode) { + // Reset the memoizedState to what it was before we attempted + // to render it. + var currentSource = sourceFiber.alternate; + + if (currentSource) { + sourceFiber.updateQueue = currentSource.updateQueue; + sourceFiber.memoizedState = currentSource.memoizedState; + sourceFiber.lanes = currentSource.lanes; + } else { + sourceFiber.updateQueue = null; + sourceFiber.memoizedState = null; } + } - case ClassComponent: { - var instance = finishedWork.stateNode; + var hasInvisibleParentBoundary = hasSuspenseContext( + suspenseStackCursor.current, + InvisibleParentSuspenseContext + ); // Schedule the nearest Suspense to re-render the timed out view. + + var _workInProgress = returnFiber; + + do { + if ( + _workInProgress.tag === SuspenseComponent && + shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary) + ) { + // Found the nearest boundary. + // Stash the promise on the boundary fiber. If the boundary times out, we'll + // attach another listener to flip the boundary back to its normal state. + var wakeables = _workInProgress.updateQueue; - if (finishedWork.flags & Update) { - if (current === null) { - // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (wakeables === null) { + var updateQueue = new Set(); + updateQueue.add(wakeable); + _workInProgress.updateQueue = updateQueue; + } else { + wakeables.add(wakeable); + } // If the boundary is outside of blocking mode, we should *not* + // suspend the commit. Pretend as if the suspended component rendered + // null and keep rendering. In the commit phase, we'll schedule a + // subsequent synchronous update to re-render the Suspense. + // + // Note: It doesn't matter whether the component that suspended was + // inside a blocking mode tree. If the Suspense is outside of it, we + // should *not* suspend the commit. - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidMount. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } + if ((_workInProgress.mode & BlockingMode) === NoMode) { + _workInProgress.flags |= DidCapture; + sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete. + // But we shouldn't call any lifecycle methods or callbacks. Remove + // all lifecycle effect tags. - { - instance.componentDidMount(); - } - } else { - var prevProps = - finishedWork.elementType === finishedWork.type - ? current.memoizedProps - : resolveDefaultProps(finishedWork.type, current.memoizedProps); - var prevState = current.memoizedState; // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete); - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + if (sourceFiber.tag === ClassComponent) { + var currentSourceFiber = sourceFiber.alternate; - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "componentDidUpdate. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } + if (currentSourceFiber === null) { + // This is a new mount. Change the tag so it's not mistaken for a + // completed class component. For example, we should not call + // componentWillUnmount if it is deleted. + sourceFiber.tag = IncompleteClassComponent; + } else { + // When we try rendering again, we should not reuse the current fiber, + // since it's known to be in an inconsistent state. Use a force update to + // prevent a bail out. + var update = createUpdate(NoTimestamp, SyncLane); + update.tag = ForceUpdate; + enqueueUpdate(sourceFiber, update); } + } // The source fiber did not complete. Mark it with Sync priority to + // indicate that it still has pending work. - { - instance.componentDidUpdate( - prevProps, - prevState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - } - } // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. + sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane); // Exit without suspending. - var updateQueue = finishedWork.updateQueue; + return; + } // Confirmed that the boundary is in a concurrent mode tree. Continue + // with the normal suspend path. + // + // After this we'll use a set of heuristics to determine whether this + // render pass will run to completion or restart or "suspend" the commit. + // The actual logic for this is spread out in different places. + // + // This first principle is that if we're going to suspend when we complete + // a root, then we should also restart if we get an update or ping that + // might unsuspend it, and vice versa. The only reason to suspend is + // because you think you might want to restart before committing. However, + // it doesn't make sense to restart only while in the period we're suspended. + // + // Restarting too aggressively is also not good because it starves out any + // intermediate loading state. So we use heuristics to determine when. + // Suspense Heuristics + // + // If nothing threw a Promise or all the same fallbacks are already showing, + // then don't suspend/restart. + // + // If this is an initial render of a new tree of Suspense boundaries and + // those trigger a fallback, then don't suspend/restart. We want to ensure + // that we can show the initial loading state as quickly as possible. + // + // If we hit a "Delayed" case, such as when we'd switch from content back into + // a fallback, then we should always suspend/restart. Transitions apply + // to this case. If none is defined, JND is used instead. + // + // If we're already showing a fallback and it gets "retried", allowing us to show + // another level, but there's still an inner boundary that would show a fallback, + // then we suspend/restart for 500ms since the last time we showed a fallback + // anywhere in the tree. This effectively throttles progressive loading into a + // consistent train of commits. This also gives us an opportunity to restart to + // get to the completed state slightly earlier. + // + // If there's ambiguity due to batching it's resolved in preference of: + // 1) "delayed", 2) "initial render", 3) "retry". + // + // We want to ensure that a "busy" state doesn't get force committed. We want to + // ensure that new initial loading states can commit as soon as possible. - if (updateQueue !== null) { - { - if ( - finishedWork.type === finishedWork.elementType && - !didWarnAboutReassigningProps - ) { - if (instance.props !== finishedWork.memoizedProps) { - error( - "Expected %s props to match memoized props before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.props`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } + attachPingListener(root, wakeable, rootRenderLanes); + _workInProgress.flags |= ShouldCapture; + _workInProgress.lanes = rootRenderLanes; + return; + } // This boundary already captured during this render. Continue to the next + // boundary. - if (instance.state !== finishedWork.memoizedState) { - error( - "Expected %s state to match memoized state before " + - "processing the update queue. " + - "This might either be because of a bug in React, or because " + - "a component reassigns its own `this.state`. " + - "Please file an issue.", - getComponentName(finishedWork.type) || "instance" - ); - } - } - } // We could update instance props and state here, - // but instead we rely on them being set during last render. - // TODO: revisit this when we implement resuming. + _workInProgress = _workInProgress.return; + } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode. + // TODO: Use invariant so the message is stripped in prod? - commitUpdateQueue(finishedWork, updateQueue, instance); - } + value = new Error( + (getComponentName(sourceFiber.type) || "A React component") + + " suspended while rendering, but no fallback UI was specified.\n" + + "\n" + + "Add a component higher in the tree to " + + "provide a loading indicator or placeholder to display." + ); + } // We didn't find a boundary that could handle this type of exception. Start + // over and traverse parent path again, this time treating the exception + // as an error. - break; - } + renderDidError(); + value = createCapturedValue(value, sourceFiber); + var workInProgress = returnFiber; + do { + switch (workInProgress.tag) { case HostRoot: { - // TODO: I think this is now always non-null by the time it reaches the - // commit phase. Consider removing the type check. - var _updateQueue = finishedWork.updateQueue; - - if (_updateQueue !== null) { - var _instance = null; - - if (finishedWork.child !== null) { - switch (finishedWork.child.tag) { - case HostComponent: - _instance = getPublicInstance(finishedWork.child.stateNode); - break; - - case ClassComponent: - _instance = finishedWork.child.stateNode; - break; - } - } + var _errorInfo = value; + workInProgress.flags |= ShouldCapture; + var lane = pickArbitraryLane(rootRenderLanes); + workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); - commitUpdateQueue(finishedWork, _updateQueue, _instance); - } + var _update = createRootErrorUpdate(workInProgress, _errorInfo, lane); - break; + enqueueCapturedUpdate(workInProgress, _update); + return; } - case HostComponent: { - var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted - // (eg DOM renderer may schedule auto-focus for inputs and form controls). - // These effects should only be committed when components are first mounted, - // aka when there is no current/alternate. + case ClassComponent: + // Capture and retry + var errorInfo = value; + var ctor = workInProgress.type; + var instance = workInProgress.stateNode; - if (current === null && finishedWork.flags & Update) { - var type = finishedWork.type; - var props = finishedWork.memoizedProps; - } + if ( + (workInProgress.flags & DidCapture) === NoFlags && + (typeof ctor.getDerivedStateFromError === "function" || + (instance !== null && + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance))) + ) { + workInProgress.flags |= ShouldCapture; - break; - } + var _lane = pickArbitraryLane(rootRenderLanes); - case HostText: { - // We have no life-cycles associated with text. - break; - } + workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state - case HostPortal: { - // We have no life-cycles associated with portals. - break; - } + var _update2 = createClassErrorUpdate( + workInProgress, + errorInfo, + _lane + ); - case Profiler: { - { - var _finishedWork$memoize2 = finishedWork.memoizedProps, - onCommit = _finishedWork$memoize2.onCommit, - onRender = _finishedWork$memoize2.onRender; - var effectDuration = finishedWork.stateNode.effectDuration; - var commitTime = getCommitTime(); - var phase = current === null ? "mount" : "update"; - - if (typeof onRender === "function") { - { - onRender( - finishedWork.memoizedProps.id, - phase, - finishedWork.actualDuration, - finishedWork.treeBaseDuration, - finishedWork.actualStartTime, - commitTime, - finishedRoot.memoizedInteractions - ); - } - } + enqueueCapturedUpdate(workInProgress, _update2); + return; } break; - } - - case SuspenseComponent: { - break; - } - - case SuspenseListComponent: - case IncompleteClassComponent: - case ScopeComponent: - case OffscreenComponent: - case LegacyHiddenComponent: - break; - - default: { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } } - } - { - if (finishedWork.flags & Ref) { - commitAttachRef(finishedWork); - } - } + workInProgress = workInProgress.return; + } while (workInProgress !== null); } -function hideOrUnhideAllChildren(finishedWork, isHidden) { - { - // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. - var node = finishedWork; - - while (true) { - if (node.tag === HostComponent) { - var instance = node.stateNode; - - if (isHidden) { - hideInstance(instance); - } else { - unhideInstance(node.stateNode, node.memoizedProps); - } - } else if (node.tag === HostText) { - var _instance3 = node.stateNode; +var didWarnAboutUndefinedSnapshotBeforeUpdate = null; - if (isHidden) { - hideTextInstance(); - } else { - unhideTextInstance(_instance3, node.memoizedProps); - } - } else if ( - (node.tag === OffscreenComponent || - node.tag === LegacyHiddenComponent) && - node.memoizedState !== null && - node !== finishedWork - ); - else if (node.child !== null) { - node.child.return = node; - node = node.child; - continue; - } +{ + didWarnAboutUndefinedSnapshotBeforeUpdate = new Set(); +} - if (node === finishedWork) { - return; - } +var PossiblyWeakSet = typeof WeakSet === "function" ? WeakSet : Set; - while (node.sibling === null) { - if (node.return === null || node.return === finishedWork) { - return; - } +var callComponentWillUnmountWithTimer = function(current, instance) { + instance.props = current.memoizedProps; + instance.state = current.memoizedState; - node = node.return; - } + { + instance.componentWillUnmount(); + } +}; // Capture errors so they don't interrupt unmounting. - node.sibling.return = node.return; - node = node.sibling; +function safelyCallComponentWillUnmount(current, instance) { + { + invokeGuardedCallback( + null, + callComponentWillUnmountWithTimer, + null, + current, + instance + ); + + if (hasCaughtError()) { + var unmountError = clearCaughtError(); + captureCommitPhaseError(current, unmountError); } } } -function commitAttachRef(finishedWork) { - var ref = finishedWork.ref; +function safelyDetachRef(current) { + var ref = current.ref; if (ref !== null) { - var instance = finishedWork.stateNode; - var instanceToUse; - - switch (finishedWork.tag) { - case HostComponent: - instanceToUse = getPublicInstance(instance); - break; - - default: - instanceToUse = instance; - } // Moved outside to ensure DCE works with this flag - if (typeof ref === "function") { { - ref(instanceToUse); - } - } else { - { - if (!ref.hasOwnProperty("current")) { - error( - "Unexpected ref object provided for %s. " + - "Use either a ref-setter function or React.createRef().", - getComponentName(finishedWork.type) - ); + { + invokeGuardedCallback(null, ref, null, null); } - } - ref.current = instanceToUse; + if (hasCaughtError()) { + var refError = clearCaughtError(); + captureCommitPhaseError(current, refError); + } + } + } else { + ref.current = null; } } } -function commitDetachRef(current) { - var currentRef = current.ref; +function safelyCallDestroy(current, destroy) { + { + invokeGuardedCallback(null, destroy, null); - if (currentRef !== null) { - if (typeof currentRef === "function") { - { - currentRef(null); - } - } else { - currentRef.current = null; + if (hasCaughtError()) { + var error = clearCaughtError(); + captureCommitPhaseError(current, error); } } -} // User-originating errors (lifecycles and refs) should not interrupt -// deletion, so don't let them throw. Host-originating errors should -// interrupt deletion, so it's okay - -function commitUnmount( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel -) { - onCommitUnmount(current); +} - switch (current.tag) { +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: - case MemoComponent: case SimpleMemoComponent: { - var updateQueue = current.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; + return; + } - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; + case ClassComponent: { + if (finishedWork.flags & Snapshot) { + if (current !== null) { + var prevProps = current.memoizedProps; + var prevState = current.memoizedState; + var instance = finishedWork.stateNode; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - do { - var _effect = effect, - destroy = _effect.destroy, - tag = _effect.tag; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (destroy !== undefined) { - if ((tag & Layout) !== NoFlags$1) { - { - safelyCallDestroy(current, nearestMountedAncestor, destroy); - } + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "getSnapshotBeforeUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); } } + } - effect = effect.next; - } while (effect !== firstEffect); - } - } + var snapshot = instance.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); - return; - } + { + var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate; - case ClassComponent: { - safelyDetachRef(current, nearestMountedAncestor); - var instance = current.stateNode; + if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) { + didWarnSet.add(finishedWork.type); - if (typeof instance.componentWillUnmount === "function") { - safelyCallComponentWillUnmount( - current, - nearestMountedAncestor, - instance - ); - } + error( + "%s.getSnapshotBeforeUpdate(): A snapshot value (or null) " + + "must be returned. You have returned undefined.", + getComponentName(finishedWork.type) + ); + } + } - return; - } + instance.__reactInternalSnapshotBeforeUpdate = snapshot; + } + } - case HostComponent: { - safelyDetachRef(current, nearestMountedAncestor); return; } - case HostPortal: { - // TODO: this is recursive. - // We are also not using this parent because - // the portal will get pushed immediately. + case HostRoot: { { - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); + if (finishedWork.flags & Snapshot) { + var root = finishedWork.stateNode; + clearContainer(root.containerInfo); + } } return; } - case DehydratedFragment: { - return; - } - - case ScopeComponent: { - return; - } - } -} - -function commitNestedUnmounts( - finishedRoot, - root, - nearestMountedAncestor, - renderPriorityLevel -) { - // While we're inside a removed host node we don't want to call - // removeChild on the inner nodes because they're removed by the top - // call anyway. We also want to call componentWillUnmount on all - // composites before this host node is removed from the tree. Therefore - // we do an inner loop while we're still inside the host node. - var node = root; - - while (true) { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes. - // Skip portals because commitUnmount() currently visits them recursively. - - if ( - node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. - // If we don't use mutation we drill down into portals here instead. - node.tag !== HostPortal - ) { - node.child.return = node; - node = node.child; - continue; - } - - if (node === root) { - return; - } - - while (node.sibling === null) { - if (node.return === null || node.return === root) { - return; - } - - node = node.return; - } - - node.sibling.return = node.return; - node = node.sibling; - } -} - -function detachFiberMutation(fiber) { - // Cut off the return pointer to disconnect it from the tree. - // This enables us to detect and warn against state updates on an unmounted component. - // It also prevents events from bubbling from within disconnected components. - // - // Ideally, we should also clear the child pointer of the parent alternate to let this - // get GC:ed but we don't know which for sure which parent is the current - // one so we'll settle for GC:ing the subtree of this child. - // This child itself will be GC:ed when the parent updates the next time. - // - // Note that we can't clear child or sibling pointers yet. - // They're needed for passive effects and for findDOMNode. - // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects). - // - // Don't reset the alternate yet, either. We need that so we can detach the - // alternate's fields in the passive phase. Clearing the return pointer is - // sufficient for findDOMNode semantics. - fiber.return = null; -} - -function detachFiberAfterEffects(fiber) { - // Null out fields to improve GC for references that may be lingering (e.g. DevTools). - // Note that we already cleared the return pointer in detachFiberMutation(). - fiber.alternate = null; - fiber.child = null; - fiber.deletions = null; - fiber.dependencies = null; - fiber.memoizedProps = null; - fiber.memoizedState = null; - fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; - fiber.updateQueue = null; - - { - fiber._debugOwner = null; - } -} - -function getHostParentFiber(fiber) { - var parent = fiber.return; - - while (parent !== null) { - if (isHostParent(parent)) { - return parent; - } - - parent = parent.return; + case HostComponent: + case HostText: + case HostPortal: + case IncompleteClassComponent: + // Nothing to do for these component types + return; } { throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." ); } } -function isHostParent(fiber) { - return ( - fiber.tag === HostComponent || - fiber.tag === HostRoot || - fiber.tag === HostPortal - ); -} +function commitHookEffectListUnmount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; -function getHostSibling(fiber) { - // We're going to search forward into the tree until we find a sibling host - // node. Unfortunately, if multiple insertions are done in a row we have to - // search past them. This leads to exponential search for the next sibling. - // TODO: Find a more efficient way to do this. - var node = fiber; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - siblings: while (true) { - // If we didn't find anything, let's try the next sibling. - while (node.sibling === null) { - if (node.return === null || isHostParent(node.return)) { - // If we pop out of the root or hit the parent the fiber we are the - // last sibling. - return null; + do { + if ((effect.tag & tag) === tag) { + // Unmount + var destroy = effect.destroy; + effect.destroy = undefined; + + if (destroy !== undefined) { + destroy(); + } } - node = node.return; - } + effect = effect.next; + } while (effect !== firstEffect); + } +} - node.sibling.return = node.return; - node = node.sibling; +function commitHookEffectListMount(tag, finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - while ( - node.tag !== HostComponent && - node.tag !== HostText && - node.tag !== DehydratedFragment - ) { - // If it is not host node and, we might have a host node inside it. - // Try to search down until we find one. - if (node.flags & Placement) { - // If we don't have a child, try the siblings instead. - continue siblings; - } // If we don't have a child, try the siblings instead. - // We also skip portals because they are not part of this host tree. + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - if (node.child === null || node.tag === HostPortal) { - continue siblings; - } else { - node.child.return = node; - node = node.child; + do { + if ((effect.tag & tag) === tag) { + // Mount + var create = effect.create; + effect.destroy = create(); + + { + var destroy = effect.destroy; + + if (destroy !== undefined && typeof destroy !== "function") { + var addendum = void 0; + + if (destroy === null) { + addendum = + " You returned null. If your effect does not require clean " + + "up, return undefined (or nothing)."; + } else if (typeof destroy.then === "function") { + addendum = + "\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. " + + "Instead, write the async function inside your effect " + + "and call it immediately:\n\n" + + "useEffect(() => {\n" + + " async function fetchData() {\n" + + " // You can await here\n" + + " const response = await MyAPI.getData(someId);\n" + + " // ...\n" + + " }\n" + + " fetchData();\n" + + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + + "Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching"; + } else { + addendum = " You returned: " + destroy; + } + + error( + "An effect function must not return anything besides a function, " + + "which is used for clean-up.%s", + addendum + ); + } + } } - } // Check if this host node is stable or about to be placed. - if (!(node.flags & Placement)) { - // Found it! - return node.stateNode; - } + effect = effect.next; + } while (effect !== firstEffect); } } -function commitPlacement(finishedWork) { - var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. +function schedulePassiveEffects(finishedWork) { + var updateQueue = finishedWork.updateQueue; + var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null; - var parent; - var isContainer; - var parentStateNode = parentFiber.stateNode; + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - switch (parentFiber.tag) { - case HostComponent: - parent = parentStateNode; - isContainer = false; - break; + do { + var _effect = effect, + next = _effect.next, + tag = _effect.tag; - case HostRoot: - parent = parentStateNode.containerInfo; - isContainer = true; - break; + if ((tag & Passive$1) !== NoFlags$1 && (tag & HasEffect) !== NoFlags$1) { + enqueuePendingPassiveHookEffectUnmount(finishedWork, effect); + enqueuePendingPassiveHookEffectMount(finishedWork, effect); + } - case HostPortal: - parent = parentStateNode.containerInfo; - isContainer = true; - break; - // eslint-disable-next-line-no-fallthrough + effect = next; + } while (effect !== firstEffect); + } +} - default: { - throw Error( - "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." - ); +function commitLifeCycles(finishedRoot, current, finishedWork, committedLanes) { + switch (finishedWork.tag) { + case FunctionComponent: + case ForwardRef: + case SimpleMemoComponent: { + // At this point layout effects have already been destroyed (during mutation phase). + // This is done to prevent sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. + { + commitHookEffectListMount(Layout | HasEffect, finishedWork); + } + + schedulePassiveEffects(finishedWork); + return; } - } - if (parentFiber.flags & ContentReset) { - parentFiber.flags &= ~ContentReset; - } + case ClassComponent: { + var instance = finishedWork.stateNode; - var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its - // children to find all the terminal nodes. + if (finishedWork.flags & Update) { + if (current === null) { + // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (isContainer) { - insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); - } else { - insertOrAppendPlacementNode(finishedWork, before, parent); - } -} + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidMount. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } -function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; + { + instance.componentDidMount(); + } + } else { + var prevProps = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps(finishedWork.type, current.memoizedProps); + var prevState = current.memoizedState; // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - if (isHost) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (before) { - insertInContainerBefore(parent); - } else { - appendChildToContainer(parent, stateNode); - } - } else if (tag === HostPortal); - else { - var child = node.child; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "componentDidUpdate. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } + + { + instance.componentDidUpdate( + prevProps, + prevState, + instance.__reactInternalSnapshotBeforeUpdate + ); + } + } + } // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + + var updateQueue = finishedWork.updateQueue; + + if (updateQueue !== null) { + { + if ( + finishedWork.type === finishedWork.elementType && + !didWarnAboutReassigningProps + ) { + if (instance.props !== finishedWork.memoizedProps) { + error( + "Expected %s props to match memoized props before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.props`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } - if (child !== null) { - insertOrAppendPlacementNodeIntoContainer(child, before, parent); - var sibling = child.sibling; + if (instance.state !== finishedWork.memoizedState) { + error( + "Expected %s state to match memoized state before " + + "processing the update queue. " + + "This might either be because of a bug in React, or because " + + "a component reassigns its own `this.state`. " + + "Please file an issue.", + getComponentName(finishedWork.type) || "instance" + ); + } + } + } // We could update instance props and state here, + // but instead we rely on them being set during last render. + // TODO: revisit this when we implement resuming. - while (sibling !== null) { - insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); - sibling = sibling.sibling; + commitUpdateQueue(finishedWork, updateQueue, instance); } + + return; } - } -} -function insertOrAppendPlacementNode(node, before, parent) { - var tag = node.tag; - var isHost = tag === HostComponent || tag === HostText; + case HostRoot: { + // TODO: I think this is now always non-null by the time it reaches the + // commit phase. Consider removing the type check. + var _updateQueue = finishedWork.updateQueue; - if (isHost) { - var stateNode = isHost ? node.stateNode : node.stateNode.instance; + if (_updateQueue !== null) { + var _instance = null; - if (before) { - insertBefore(parent, stateNode, before); - } else { - appendChild(parent, stateNode); - } - } else if (tag === HostPortal); - else { - var child = node.child; + if (finishedWork.child !== null) { + switch (finishedWork.child.tag) { + case HostComponent: + _instance = getPublicInstance(finishedWork.child.stateNode); + break; - if (child !== null) { - insertOrAppendPlacementNode(child, before, parent); - var sibling = child.sibling; + case ClassComponent: + _instance = finishedWork.child.stateNode; + break; + } + } - while (sibling !== null) { - insertOrAppendPlacementNode(sibling, before, parent); - sibling = sibling.sibling; + commitUpdateQueue(finishedWork, _updateQueue, _instance); } - } - } -} - -function unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel -) { - // We only have the top Fiber that was deleted but we need to recurse down its - // children to find all the terminal nodes. - var node = current; // Each iteration, currentParent is populated with node's host parent if not - // currentParentIsValid. - var currentParentIsValid = false; // Note: these two variables *must* always be updated together. + return; + } - var currentParent; - var currentParentIsContainer; + case HostComponent: { + var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted + // (eg DOM renderer may schedule auto-focus for inputs and form controls). + // These effects should only be committed when components are first mounted, + // aka when there is no current/alternate. - while (true) { - if (!currentParentIsValid) { - var parent = node.return; + if (current === null && finishedWork.flags & Update) { + var type = finishedWork.type; + var props = finishedWork.memoizedProps; + } - findParent: while (true) { - if (!(parent !== null)) { - throw Error( - "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." - ); - } + return; + } - var parentStateNode = parent.stateNode; + case HostText: { + // We have no life-cycles associated with text. + return; + } - switch (parent.tag) { - case HostComponent: - currentParent = parentStateNode; - currentParentIsContainer = false; - break findParent; + case HostPortal: { + // We have no life-cycles associated with portals. + return; + } - case HostRoot: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + case Profiler: { + { + var _finishedWork$memoize2 = finishedWork.memoizedProps, + onCommit = _finishedWork$memoize2.onCommit, + onRender = _finishedWork$memoize2.onRender; + var effectDuration = finishedWork.stateNode.effectDuration; + var commitTime = getCommitTime(); - case HostPortal: - currentParent = parentStateNode.containerInfo; - currentParentIsContainer = true; - break findParent; + if (typeof onRender === "function") { + { + onRender( + finishedWork.memoizedProps.id, + current === null ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + commitTime, + finishedRoot.memoizedInteractions + ); + } } - - parent = parent.return; } - currentParentIsValid = true; + return; } - if (node.tag === HostComponent || node.tag === HostText) { - commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the - // node from the tree. + case SuspenseComponent: { + return; + } - if (currentParentIsContainer) { - removeChildFromContainer(currentParent, node.stateNode); - } else { - removeChild(currentParent, node.stateNode); - } // Don't visit children because we already visited them. - } else if (node.tag === HostPortal) { - if (node.child !== null) { - // When we go into a portal, it becomes the parent to remove from. - // We will reassign it back when we pop the portal on the way up. - currentParent = node.stateNode.containerInfo; - currentParentIsContainer = true; // Visit children because portals might contain host components. + case SuspenseListComponent: + case IncompleteClassComponent: + case FundamentalComponent: + case ScopeComponent: + case OffscreenComponent: + case LegacyHiddenComponent: + return; + } - node.child.return = node; - node = node.child; - continue; - } - } else { - commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below. + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); + } +} - if (node.child !== null) { +function hideOrUnhideAllChildren(finishedWork, isHidden) { + { + // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. + var node = finishedWork; + + while (true) { + if (node.tag === HostComponent) { + var instance = node.stateNode; + + if (isHidden) { + hideInstance(instance); + } else { + unhideInstance(node.stateNode, node.memoizedProps); + } + } else if (node.tag === HostText) { + var _instance3 = node.stateNode; + + if (isHidden) { + hideTextInstance(); + } else { + unhideTextInstance(_instance3, node.memoizedProps); + } + } else if ( + (node.tag === OffscreenComponent || + node.tag === LegacyHiddenComponent) && + node.memoizedState !== null && + node !== finishedWork + ); + else if (node.child !== null) { node.child.return = node; node = node.child; continue; } - } - - if (node === current) { - return; - } - while (node.sibling === null) { - if (node.return === null || node.return === current) { + if (node === finishedWork) { return; } - node = node.return; + while (node.sibling === null) { + if (node.return === null || node.return === finishedWork) { + return; + } - if (node.tag === HostPortal) { - // When we go out of the portal, we need to restore the parent. - // Since we don't keep a stack of them, we will search for it. - currentParentIsValid = false; + node = node.return; } - } - node.sibling.return = node.return; - node = node.sibling; + node.sibling.return = node.return; + node = node.sibling; + } } } -function commitDeletion( - finishedRoot, - current, - nearestMountedAncestor, - renderPriorityLevel -) { - { - // Recursively delete all host nodes from the parent. - // Detach refs and call componentWillUnmount() on the whole subtree. - unmountHostComponents(finishedRoot, current, nearestMountedAncestor); - } +function commitAttachRef(finishedWork) { + var ref = finishedWork.ref; - var alternate = current.alternate; - detachFiberMutation(current); + if (ref !== null) { + var instance = finishedWork.stateNode; + var instanceToUse; - if (alternate !== null) { - detachFiberMutation(alternate); - } -} + switch (finishedWork.tag) { + case HostComponent: + instanceToUse = getPublicInstance(instance); + break; -function commitWork(current, finishedWork) { - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case MemoComponent: - case SimpleMemoComponent: { - // Layout effects are destroyed during the mutation phase so that all - // destroy functions for all fibers are called before any create functions. - // This prevents sibling component effects from interfering with each other, - // e.g. a destroy function in one component should never override a ref set - // by a create function in another component during the same commit. + default: + instanceToUse = instance; + } // Moved outside to ensure DCE works with this flag + + if (typeof ref === "function") { { - commitHookEffectListUnmount( - Layout | HasEffect, - finishedWork, - finishedWork.return - ); + ref(instanceToUse); + } + } else { + { + if (!ref.hasOwnProperty("current")) { + error( + "Unexpected ref object provided for %s. " + + "Use either a ref-setter function or React.createRef().", + getComponentName(finishedWork.type) + ); + } } - return; + ref.current = instanceToUse; } + } +} - case ClassComponent: { - return; +function commitDetachRef(current) { + var currentRef = current.ref; + + if (currentRef !== null) { + if (typeof currentRef === "function") { + { + currentRef(null); + } + } else { + currentRef.current = null; } + } +} // User-originating errors (lifecycles and refs) should not interrupt +// deletion, so don't let them throw. Host-originating errors should +// interrupt deletion, so it's okay + +function commitUnmount(finishedRoot, current, renderPriorityLevel) { + onCommitUnmount(current); - case HostComponent: { - var instance = finishedWork.stateNode; + switch (current.tag) { + case FunctionComponent: + case ForwardRef: + case MemoComponent: + case SimpleMemoComponent: { + var updateQueue = current.updateQueue; - if (instance != null) { - // Commit the work prepared earlier. - var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + if (updateQueue !== null) { + var lastEffect = updateQueue.lastEffect; - var oldProps = current !== null ? current.memoizedProps : newProps; - var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. + if (lastEffect !== null) { + var firstEffect = lastEffect.next; + var effect = firstEffect; - var updatePayload = finishedWork.updateQueue; - finishedWork.updateQueue = null; + do { + var _effect2 = effect, + destroy = _effect2.destroy, + tag = _effect2.tag; - if (updatePayload !== null) { - commitUpdate(instance, updatePayload, type, oldProps, newProps); + if (destroy !== undefined) { + if ((tag & Passive$1) !== NoFlags$1) { + enqueuePendingPassiveHookEffectUnmount(current, effect); + } else { + { + safelyCallDestroy(current, destroy); + } + } + } + + effect = effect.next; + } while (effect !== firstEffect); } } return; } - case HostText: { - if (!(finishedWork.stateNode !== null)) { - throw Error( - "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." - ); - } + case ClassComponent: { + safelyDetachRef(current); + var instance = current.stateNode; - var textInstance = finishedWork.stateNode; - var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps - // as the newProps. The updatePayload will contain the real change in - // this case. + if (typeof instance.componentWillUnmount === "function") { + safelyCallComponentWillUnmount(current, instance); + } - var oldText = current !== null ? current.memoizedProps : newText; - commitTextUpdate(textInstance, oldText, newText); return; } - case HostRoot: { + case HostComponent: { + safelyDetachRef(current); return; } - case Profiler: { - return; - } + case HostPortal: { + // TODO: this is recursive. + // We are also not using this parent because + // the portal will get pushed immediately. + { + unmountHostComponents(finishedRoot, current); + } - case SuspenseComponent: { - commitSuspenseComponent(finishedWork); - attachSuspenseRetryListeners(finishedWork); return; } - case SuspenseListComponent: { - attachSuspenseRetryListeners(finishedWork); + case FundamentalComponent: { return; } - case IncompleteClassComponent: { + case DehydratedFragment: { return; } case ScopeComponent: { - break; - } - - case OffscreenComponent: - case LegacyHiddenComponent: { - var newState = finishedWork.memoizedState; - var isHidden = newState !== null; - hideOrUnhideAllChildren(finishedWork, isHidden); return; } } - - { - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } } -function commitSuspenseComponent(finishedWork) { - var newState = finishedWork.memoizedState; +function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) { + // While we're inside a removed host node we don't want to call + // removeChild on the inner nodes because they're removed by the top + // call anyway. We also want to call componentWillUnmount on all + // composites before this host node is removed from the tree. Therefore + // we do an inner loop while we're still inside the host node. + var node = root; - if (newState !== null) { - markCommitTimeOfFallback(); + while (true) { + commitUnmount(finishedRoot, node); // Visit children because they may contain more composite or host nodes. + // Skip portals because commitUnmount() currently visits them recursively. - { - // Hide the Offscreen component that contains the primary children. TODO: - // Ideally, this effect would have been scheduled on the Offscreen fiber - // itself. That's how unhiding works: the Offscreen component schedules an - // effect on itself. However, in this case, the component didn't complete, - // so the fiber was never added to the effect list in the normal path. We - // could have appended it to the effect list in the Suspense component's - // second pass, but doing it this way is less complicated. This would be - // simpler if we got rid of the effect list and traversed the tree, like - // we're planning to do. - var primaryChildParent = finishedWork.child; - hideOrUnhideAllChildren(primaryChildParent, true); + if ( + node.child !== null && // If we use mutation we drill down into portals using commitUnmount above. + // If we don't use mutation we drill down into portals here instead. + node.tag !== HostPortal + ) { + node.child.return = node; + node = node.child; + continue; } - } -} - -function attachSuspenseRetryListeners(finishedWork) { - // If this boundary just timed out, then it will have a set of wakeables. - // For each wakeable, attach a listener so that when it resolves, React - // attempts to re-render the boundary in the primary (pre-timeout) state. - var wakeables = finishedWork.updateQueue; - - if (wakeables !== null) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - if (retryCache === null) { - retryCache = finishedWork.stateNode = new PossiblyWeakSet(); + if (node === root) { + return; } - wakeables.forEach(function(wakeable) { - // Memoize using the boundary fiber to prevent redundant listeners. - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - - if (!retryCache.has(wakeable)) { - { - if (wakeable.__reactDoNotTraceInteractions !== true) { - retry = tracing.unstable_wrap(retry); - } - } - - retryCache.add(wakeable); - wakeable.then(retry, retry); + while (node.sibling === null) { + if (node.return === null || node.return === root) { + return; } - }); - } -} // This function detects when a Suspense boundary goes from visible to hidden. -// It returns false if the boundary is already hidden. -// TODO: Use an effect tag. - -function isSuspenseBoundaryBeingHidden(current, finishedWork) { - if (current !== null) { - var oldState = current.memoizedState; - if (oldState === null || oldState.dehydrated !== null) { - var newState = finishedWork.memoizedState; - return newState !== null && newState.dehydrated === null; + node = node.return; } - } - return false; + node.sibling.return = node.return; + node = node.sibling; + } } -function commitResetTextContent(current) { - resetTextContent(current.stateNode); -} +function detachFiberMutation(fiber) { + // Cut off the return pointers to disconnect it from the tree. Ideally, we + // should clear the child pointer of the parent alternate to let this + // get GC:ed but we don't know which for sure which parent is the current + // one so we'll settle for GC:ing the subtree of this child. This child + // itself will be GC:ed when the parent updates the next time. + // Note: we cannot null out sibling here, otherwise it can cause issues + // with findDOMNode and how it requires the sibling field to carry out + // traversal in a later effect. See PR #16820. We now clear the sibling + // field after effects, see: detachFiberAfterEffects. + // + // Don't disconnect stateNode now; it will be detached in detachFiberAfterEffects. + // It may be required if the current component is an error boundary, + // and one of its descendants throws while unmounting a passive effect. + fiber.alternate = null; + fiber.child = null; + fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; + fiber.memoizedProps = null; + fiber.memoizedState = null; + fiber.pendingProps = null; + fiber.return = null; + fiber.updateQueue = null; -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - nextEffect = firstChild; - commitMutationEffects_begin(root, renderPriorityLevel); + { + fiber._debugOwner = null; + } } -function commitMutationEffects_begin(root, renderPriorityLevel) { - while (nextEffect !== null) { - var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization - - var deletions = fiber.deletions; - - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var childToDelete = deletions[i]; - - { - invokeGuardedCallback( - null, - commitDeletion, - null, - root, - childToDelete, - fiber, - renderPriorityLevel - ); +function getHostParentFiber(fiber) { + var parent = fiber.return; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(childToDelete, fiber, error); - } - } - } + while (parent !== null) { + if (isHostParent(parent)) { + return parent; } - var child = fiber.child; + parent = parent.return; + } - if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitMutationEffects_complete(root, renderPriorityLevel); - } + { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitMutationEffects_complete(root, renderPriorityLevel) { - while (nextEffect !== null) { - var fiber = nextEffect; +function isHostParent(fiber) { + return ( + fiber.tag === HostComponent || + fiber.tag === HostRoot || + fiber.tag === HostPortal + ); +} - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitMutationEffectsOnFiber, - null, - fiber, - root, - renderPriorityLevel - ); +function getHostSibling(fiber) { + // We're going to search forward into the tree until we find a sibling host + // node. Unfortunately, if multiple insertions are done in a row we have to + // search past them. This leads to exponential search for the next sibling. + // TODO: Find a more efficient way to do this. + var node = fiber; - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); + siblings: while (true) { + // If we didn't find anything, let's try the next sibling. + while (node.sibling === null) { + if (node.return === null || isHostParent(node.return)) { + // If we pop out of the root or hit the parent the fiber we are the + // last sibling. + return null; } - resetCurrentFiber(); + node = node.return; } - var sibling = fiber.sibling; + node.sibling.return = node.return; + node = node.sibling; + + while ( + node.tag !== HostComponent && + node.tag !== HostText && + node.tag !== DehydratedFragment + ) { + // If it is not host node and, we might have a host node inside it. + // Try to search down until we find one. + if (node.flags & Placement) { + // If we don't have a child, try the siblings instead. + continue siblings; + } // If we don't have a child, try the siblings instead. + // We also skip portals because they are not part of this host tree. + + if (node.child === null || node.tag === HostPortal) { + continue siblings; + } else { + node.child.return = node; + node = node.child; + } + } // Check if this host node is stable or about to be placed. - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; + if (!(node.flags & Placement)) { + // Found it! + return node.stateNode; } - - nextEffect = fiber.return; } } -function commitMutationEffectsOnFiber(finishedWork, root, renderPriorityLevel) { - var flags = finishedWork.flags; +function commitPlacement(finishedWork) { + var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together. - if (flags & ContentReset) { - commitResetTextContent(finishedWork); - } + var parent; + var isContainer; + var parentStateNode = parentFiber.stateNode; - if (flags & Ref) { - var current = finishedWork.alternate; + switch (parentFiber.tag) { + case HostComponent: + parent = parentStateNode; + isContainer = false; + break; - if (current !== null) { - commitDetachRef(current); - } - } // The following switch statement is only concerned about placement, - // updates, and deletions. To avoid needing to add a case for every possible - // bitmap value, we remove the secondary effects from the effect tag and - // switch on that value. + case HostRoot: + parent = parentStateNode.containerInfo; + isContainer = true; + break; - var primaryFlags = flags & (Placement | Update | Hydrating); + case HostPortal: + parent = parentStateNode.containerInfo; + isContainer = true; + break; - switch (primaryFlags) { - case Placement: { - commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. - // TODO: findDOMNode doesn't rely on this any more but isMounted does - // and isMounted is deprecated anyway so we should be able to kill this. + case FundamentalComponent: - finishedWork.flags &= ~Placement; - break; + // eslint-disable-next-line-no-fallthrough + + default: { + throw Error( + "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." + ); } + } - case PlacementAndUpdate: { - // Placement - commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is - // inserted, before any life-cycles like componentDidMount gets called. + if (parentFiber.flags & ContentReset) { + parentFiber.flags &= ~ContentReset; + } - finishedWork.flags &= ~Placement; // Update + var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its + // children to find all the terminal nodes. - var _current = finishedWork.alternate; - commitWork(_current, finishedWork); - break; - } + if (isContainer) { + insertOrAppendPlacementNodeIntoContainer(finishedWork, before, parent); + } else { + insertOrAppendPlacementNode(finishedWork, before, parent); + } +} - case Hydrating: { - finishedWork.flags &= ~Hydrating; - break; - } +function insertOrAppendPlacementNodeIntoContainer(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; - case HydratingAndUpdate: { - finishedWork.flags &= ~Hydrating; // Update + if (isHost || enableFundamentalAPI) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - var _current2 = finishedWork.alternate; - commitWork(_current2, finishedWork); - break; + if (before) { + insertInContainerBefore(parent); + } else { + appendChildToContainer(parent, stateNode); } + } else if (tag === HostPortal); + else { + var child = node.child; - case Update: { - var _current3 = finishedWork.alternate; - commitWork(_current3, finishedWork); - break; + if (child !== null) { + insertOrAppendPlacementNodeIntoContainer(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNodeIntoContainer(sibling, before, parent); + sibling = sibling.sibling; + } } } } -function commitLayoutEffects(finishedWork, root, committedLanes) { - nextEffect = finishedWork; - commitLayoutEffects_begin(finishedWork, root, committedLanes); -} +function insertOrAppendPlacementNode(node, before, parent) { + var tag = node.tag; + var isHost = tag === HostComponent || tag === HostText; -function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) { - while (nextEffect !== null) { - var fiber = nextEffect; - var firstChild = fiber.child; + if (isHost || enableFundamentalAPI) { + var stateNode = isHost ? node.stateNode : node.stateNode.instance; - if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); - nextEffect = firstChild; + if (before) { + insertBefore(parent, stateNode, before); } else { - commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes); + appendChild(parent, stateNode); + } + } else if (tag === HostPortal); + else { + var child = node.child; + + if (child !== null) { + insertOrAppendPlacementNode(child, before, parent); + var sibling = child.sibling; + + while (sibling !== null) { + insertOrAppendPlacementNode(sibling, before, parent); + sibling = sibling.sibling; + } } } } -function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) { - while (nextEffect !== null) { - var fiber = nextEffect; - - if ((fiber.flags & LayoutMask) !== NoFlags) { - var current = fiber.alternate; +function unmountHostComponents(finishedRoot, current, renderPriorityLevel) { + // We only have the top Fiber that was deleted but we need to recurse down its + // children to find all the terminal nodes. + var node = current; // Each iteration, currentParent is populated with node's host parent if not + // currentParentIsValid. - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitLayoutEffectOnFiber, - null, - root, - current, - fiber, - committedLanes - ); + var currentParentIsValid = false; // Note: these two variables *must* always be updated together. - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); - } + var currentParent; + var currentParentIsContainer; - resetCurrentFiber(); - } - } + while (true) { + if (!currentParentIsValid) { + var parent = node.return; - if (fiber === subtreeRoot) { - nextEffect = null; - return; - } + findParent: while (true) { + if (!(parent !== null)) { + throw Error( + "Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue." + ); + } - var sibling = fiber.sibling; + var parentStateNode = parent.stateNode; - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; - } + switch (parent.tag) { + case HostComponent: + currentParent = parentStateNode; + currentParentIsContainer = false; + break findParent; - nextEffect = fiber.return; - } -} + case HostRoot: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; -function commitPassiveMountEffects(root, finishedWork) { - nextEffect = finishedWork; - commitPassiveMountEffects_begin(finishedWork, root); -} + case HostPortal: + currentParent = parentStateNode.containerInfo; + currentParentIsContainer = true; + break findParent; + } -function commitPassiveMountEffects_begin(subtreeRoot, root) { - while (nextEffect !== null) { - var fiber = nextEffect; - var firstChild = fiber.child; + parent = parent.return; + } - if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) { - ensureCorrectReturnPointer(firstChild, fiber); - nextEffect = firstChild; - } else { - commitPassiveMountEffects_complete(subtreeRoot, root); + currentParentIsValid = true; } - } -} -function commitPassiveMountEffects_complete(subtreeRoot, root) { - while (nextEffect !== null) { - var fiber = nextEffect; + if (node.tag === HostComponent || node.tag === HostText) { + commitNestedUnmounts(finishedRoot, node); // After all the children have unmounted, it is now safe to remove the + // node from the tree. - if ((fiber.flags & Passive) !== NoFlags) { - { - setCurrentFiber(fiber); - invokeGuardedCallback( - null, - commitPassiveMountOnFiber, - null, - root, - fiber - ); + if (currentParentIsContainer) { + removeChildFromContainer(currentParent, node.stateNode); + } else { + removeChild(currentParent, node.stateNode); + } // Don't visit children because we already visited them. + } else if (node.tag === HostPortal) { + if (node.child !== null) { + // When we go into a portal, it becomes the parent to remove from. + // We will reassign it back when we pop the portal on the way up. + currentParent = node.stateNode.containerInfo; + currentParentIsContainer = true; // Visit children because portals might contain host components. - if (hasCaughtError()) { - var error = clearCaughtError(); - captureCommitPhaseError(fiber, fiber.return, error); - } + node.child.return = node; + node = node.child; + continue; + } + } else { + commitUnmount(finishedRoot, node); // Visit children because we may find more host components below. - resetCurrentFiber(); + if (node.child !== null) { + node.child.return = node; + node = node.child; + continue; } } - if (fiber === subtreeRoot) { - nextEffect = null; + if (node === current) { return; } - var sibling = fiber.sibling; + while (node.sibling === null) { + if (node.return === null || node.return === current) { + return; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; + node = node.return; + + if (node.tag === HostPortal) { + // When we go out of the portal, we need to restore the parent. + // Since we don't keep a stack of them, we will search for it. + currentParentIsValid = false; + } } - nextEffect = fiber.return; + node.sibling.return = node.return; + node = node.sibling; + } +} + +function commitDeletion(finishedRoot, current, renderPriorityLevel) { + { + // Recursively delete all host nodes from the parent. + // Detach refs and call componentWillUnmount() on the whole subtree. + unmountHostComponents(finishedRoot, current); + } + + var alternate = current.alternate; + detachFiberMutation(current); + + if (alternate !== null) { + detachFiberMutation(alternate); } } -function commitPassiveMountOnFiber(finishedRoot, finishedWork) { +function commitWork(current, finishedWork) { switch (finishedWork.tag) { case FunctionComponent: case ForwardRef: + case MemoComponent: case SimpleMemoComponent: { + // Layout effects are destroyed during the mutation phase so that all + // destroy functions for all fibers are called before any create functions. + // This prevents sibling component effects from interfering with each other, + // e.g. a destroy function in one component should never override a ref set + // by a create function in another component during the same commit. { - commitHookEffectListMount(Passive$1 | HasEffect, finishedWork); + commitHookEffectListUnmount(Layout | HasEffect, finishedWork); } - break; + return; } - } -} -function commitPassiveUnmountEffects(firstChild) { - nextEffect = firstChild; - commitPassiveUnmountEffects_begin(); -} + case ClassComponent: { + return; + } -function commitPassiveUnmountEffects_begin() { - while (nextEffect !== null) { - var fiber = nextEffect; - var child = fiber.child; + case HostComponent: { + var instance = finishedWork.stateNode; - if ((nextEffect.flags & ChildDeletion) !== NoFlags) { - var deletions = fiber.deletions; + if (instance != null) { + // Commit the work prepared earlier. + var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. - if (deletions !== null) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - nextEffect = fiberToDelete; - commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - fiberToDelete, - fiber - ); // Now that passive effects have been processed, it's safe to detach lingering pointers. + var oldProps = current !== null ? current.memoizedProps : newProps; + var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components. - var alternate = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); + var updatePayload = finishedWork.updateQueue; + finishedWork.updateQueue = null; - if (alternate !== null) { - detachFiberAfterEffects(alternate); - } + if (updatePayload !== null) { + commitUpdate(instance, updatePayload, type, oldProps, newProps); } + } + + return; + } - nextEffect = fiber; + case HostText: { + if (!(finishedWork.stateNode !== null)) { + throw Error( + "This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue." + ); } + + var textInstance = finishedWork.stateNode; + var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps + // as the newProps. The updatePayload will contain the real change in + // this case. + + var oldText = current !== null ? current.memoizedProps : newText; + commitTextUpdate(textInstance, oldText, newText); + return; } - if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitPassiveUnmountEffects_complete(); + case HostRoot: { + return; } - } -} -function commitPassiveUnmountEffects_complete() { - while (nextEffect !== null) { - var fiber = nextEffect; + case Profiler: { + return; + } - if ((fiber.flags & Passive) !== NoFlags) { - setCurrentFiber(fiber); - commitPassiveUnmountOnFiber(fiber); - resetCurrentFiber(); + case SuspenseComponent: { + commitSuspenseComponent(finishedWork); + attachSuspenseRetryListeners(finishedWork); + return; } - var sibling = fiber.sibling; + case SuspenseListComponent: { + attachSuspenseRetryListeners(finishedWork); + return; + } - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; + case IncompleteClassComponent: { return; } - nextEffect = fiber.return; - } -} + case FundamentalComponent: { + break; + } -function commitPassiveUnmountOnFiber(finishedWork) { - { - finishedWork.flags &= ~PassiveUnmountPendingDev; - var alternate = finishedWork.alternate; + case ScopeComponent: { + break; + } - if (alternate !== null) { - alternate.flags &= ~PassiveUnmountPendingDev; + case OffscreenComponent: + case LegacyHiddenComponent: { + var newState = finishedWork.memoizedState; + var isHidden = newState !== null; + hideOrUnhideAllChildren(finishedWork, isHidden); + return; } } - switch (finishedWork.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - { - commitHookEffectListUnmount( - Passive$1 | HasEffect, - finishedWork, - finishedWork.return - ); - } - - break; - } + { + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } } -function commitPassiveUnmountEffectsInsideOfDeletedTree_begin( - deletedSubtreeRoot, - nearestMountedAncestor -) { - while (nextEffect !== null) { - var fiber = nextEffect; // Deletion effects fire in parent -> child order - // TODO: Check if fiber has a PassiveStatic flag +function commitSuspenseComponent(finishedWork) { + var newState = finishedWork.memoizedState; - setCurrentFiber(fiber); - commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor); - resetCurrentFiber(); - var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag + if (newState !== null) { + markCommitTimeOfFallback(); - if (child !== null) { - ensureCorrectReturnPointer(child, fiber); - nextEffect = child; - } else { - commitPassiveUnmountEffectsInsideOfDeletedTree_complete( - deletedSubtreeRoot - ); + { + // Hide the Offscreen component that contains the primary children. TODO: + // Ideally, this effect would have been scheduled on the Offscreen fiber + // itself. That's how unhiding works: the Offscreen component schedules an + // effect on itself. However, in this case, the component didn't complete, + // so the fiber was never added to the effect list in the normal path. We + // could have appended it to the effect list in the Suspense component's + // second pass, but doing it this way is less complicated. This would be + // simpler if we got rid of the effect list and traversed the tree, like + // we're planning to do. + var primaryChildParent = finishedWork.child; + hideOrUnhideAllChildren(primaryChildParent, true); } } } -function commitPassiveUnmountEffectsInsideOfDeletedTree_complete( - deletedSubtreeRoot -) { - while (nextEffect !== null) { - var fiber = nextEffect; +function attachSuspenseRetryListeners(finishedWork) { + // If this boundary just timed out, then it will have a set of wakeables. + // For each wakeable, attach a listener so that when it resolves, React + // attempts to re-render the boundary in the primary (pre-timeout) state. + var wakeables = finishedWork.updateQueue; - if (fiber === deletedSubtreeRoot) { - nextEffect = null; - return; + if (wakeables !== null) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + + if (retryCache === null) { + retryCache = finishedWork.stateNode = new PossiblyWeakSet(); } - var sibling = fiber.sibling; + wakeables.forEach(function(wakeable) { + // Memoize using the boundary fiber to prevent redundant listeners. + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - if (sibling !== null) { - ensureCorrectReturnPointer(sibling, fiber.return); - nextEffect = sibling; - return; - } + if (!retryCache.has(wakeable)) { + { + if (wakeable.__reactDoNotTraceInteractions !== true) { + retry = tracing.unstable_wrap(retry); + } + } - nextEffect = fiber.return; + retryCache.add(wakeable); + wakeable.then(retry, retry); + } + }); } -} +} // This function detects when a Suspense boundary goes from visible to hidden. +// It returns false if the boundary is already hidden. +// TODO: Use an effect tag. -function commitPassiveUnmountInsideDeletedTreeOnFiber( - current, - nearestMountedAncestor -) { - switch (current.tag) { - case FunctionComponent: - case ForwardRef: - case SimpleMemoComponent: { - { - commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor); - } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + if (current !== null) { + var oldState = current.memoizedState; - break; + if (oldState === null || oldState.dehydrated !== null) { + var newState = finishedWork.memoizedState; + return newState !== null && newState.dehydrated === null; } } -} -var didWarnWrongReturnPointer = false; - -function ensureCorrectReturnPointer(fiber, expectedReturnFiber) { - { - if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) { - didWarnWrongReturnPointer = true; - - error( - "Internal React error: Return pointer is inconsistent " + "with parent." - ); - } - } // TODO: Remove this assignment once we're confident that it won't break - // anything, by checking the warning logs for the above invariant + return false; +} - fiber.return = expectedReturnFiber; +function commitResetTextContent(current) { + resetTextContent(current.stateNode); } var COMPONENT_TYPE = 0; @@ -18771,7 +17705,8 @@ var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an var workInProgressRootUpdatedLanes = NoLanes; // Lanes that were pinged (in an interleaved event) during this render. -var workInProgressRootPingedLanes = NoLanes; // The most recent time we committed a fallback. This lets us ensure a train +var workInProgressRootPingedLanes = NoLanes; +var mostRecentlyUpdatedRoot = null; // The most recent time we committed a fallback. This lets us ensure a train // model where we don't commit new loading states in too quick succession. var globalMostRecentFallbackTime = 0; @@ -18790,13 +17725,16 @@ function resetRenderTimer() { function getRenderTargetTime() { return workInProgressRootRenderTargetTime; } +var nextEffect = null; var hasUncaughtError = false; var firstUncaughtError = null; -var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true; +var legacyErrorBoundariesThatAlreadyFailed = null; var rootDoesHavePassiveEffects = false; var rootWithPendingPassiveEffects = null; -var pendingPassiveEffectsRenderPriority = NoPriority; +var pendingPassiveEffectsRenderPriority = NoPriority$1; var pendingPassiveEffectsLanes = NoLanes; +var pendingPassiveHookEffectsMount = []; +var pendingPassiveHookEffectsUnmount = []; var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates var NESTED_UPDATE_LIMIT = 50; @@ -18814,10 +17752,13 @@ var spawnedWorkDuringRender = null; // If two updates are scheduled within the s // between the first and second call. var currentEventTime = NoTimestamp; -var currentEventTransitionLane = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. +var currentEventWipLanes = NoLanes; +var currentEventPendingLanes = NoLanes; // Dev only flag that tracks if passive effects are currently being flushed. // We warn about state updates for unmounted components differently in this case. var isFlushingPassiveEffects = false; +var focusedInstanceHandle = null; +var shouldFireAfterActiveInstanceBlur = false; function getWorkInProgressRoot() { return workInProgressRoot; } @@ -18842,41 +17783,63 @@ function requestUpdateLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority + return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; } // The algorithm for assigning an update to a lane should be stable for all + // updates at the same priority within the same event. To do this, the inputs + // to the algorithm must be the same. For example, we use the `renderLanes` + // to avoid choosing a lane that is already in the middle of rendering. + // + // However, the "included" lanes could be mutated in between updates in the + // same event, like if you perform an update inside `flushSync`. Or any other + // code path that might call `prepareFreshStack`. + // + // The trick we use is to cache the first of each of these inputs within an + // event. Then reset the cached values once we can be sure the event is over. + // Our heuristic for that is whenever we enter a concurrent work loop. + // + // We'll do the same for `currentEventPendingLanes` below. + + if (currentEventWipLanes === NoLanes) { + currentEventWipLanes = workInProgressRootIncludedLanes; + } var isTransition = requestCurrentTransition() !== NoTransition; if (isTransition) { - if (currentEventTransitionLane === NoLane) { - currentEventTransitionLane = claimNextTransitionLane(); + if (currentEventPendingLanes !== NoLanes) { + currentEventPendingLanes = + mostRecentlyUpdatedRoot !== null + ? mostRecentlyUpdatedRoot.pendingLanes + : NoLanes; } - return currentEventTransitionLane; + return findTransitionLane(currentEventWipLanes, currentEventPendingLanes); } // TODO: Remove this dependency on the Scheduler priority. // To do that, we're replacing it with an update lane priority. - var schedulerPriority = getCurrentPriorityLevel(); // Find the correct lane based on priorities. Ideally, this would just be - // the update lane priority, but for now we're also checking for discrete - // updates and falling back to the scheduler priority. + var schedulerPriority = getCurrentPriorityLevel(); // The old behavior was using the priority level of the Scheduler. + // This couples React to the Scheduler internals, so we're replacing it + // with the currentUpdateLanePriority above. As an example of how this + // could be problematic, if we're not inside `Scheduler.runWithPriority`, + // then we'll get the priority of the current running Scheduler task, + // which is probably not what we want. var lane; if ( // TODO: Temporary. We're removing the concept of discrete updates. (executionContext & DiscreteEventContext) !== NoContext && - schedulerPriority === UserBlockingPriority + schedulerPriority === UserBlockingPriority$1 ) { - lane = findUpdateLane(InputDiscreteLanePriority); + lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes); } else { - { - var schedulerLanePriority = schedulerPriorityToLanePriority( - schedulerPriority - ); - lane = findUpdateLane(schedulerLanePriority); - } + var schedulerLanePriority = schedulerPriorityToLanePriority( + schedulerPriority + ); + + lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes); } return lane; @@ -18892,12 +17855,16 @@ function requestRetryLane(fiber) { if ((mode & BlockingMode) === NoMode) { return SyncLane; } else if ((mode & ConcurrentMode) === NoMode) { - return getCurrentPriorityLevel() === ImmediatePriority + return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane; } // See `requestUpdateLane` for explanation of `currentEventWipLanes` - return claimNextRetryLane(); + if (currentEventWipLanes === NoLanes) { + currentEventWipLanes = workInProgressRootIncludedLanes; + } + + return findRetryLane(currentEventWipLanes); } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -18970,8 +17937,8 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { if ( (executionContext & DiscreteEventContext) !== NoContext && // Only updates at user-blocking priority or greater are considered // discrete, even inside a discrete event. - (priorityLevel === UserBlockingPriority || - priorityLevel === ImmediatePriority) + (priorityLevel === UserBlockingPriority$1 || + priorityLevel === ImmediatePriority$1) ) { // This is the result of a discrete event. Track the lowest priority // discrete update per root so we can flush them early, if needed. @@ -18984,9 +17951,13 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, lane); - } + } // We use this when assigning a lane for a transition inside + // `requestUpdateLane`. We assume it's the same as the root being updated, + // since in the common case of a single root app it probably is. If it's not + // the same root, then it's not a huge deal, we just might batch more stuff + // together more than necessary. - return root; + mostRecentlyUpdatedRoot = root; } // This is split into a separate function so we can mark a fiber with pending // work without treating it as a typical update that originates from an event; // e.g. retrying a Suspense boundary isn't an update, but it does schedule work @@ -19008,7 +17979,7 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { ) { warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber); } - } // Walk the parent path to the root and update the child lanes. + } // Walk the parent path to the root and update the child expiration time. var node = sourceFiber; var parent = sourceFiber.return; @@ -19037,20 +18008,6 @@ function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { } else { return null; } -} - -function isInterleavedUpdate(fiber, lane) { - return ( - // TODO: Optimize slightly by comparing to root that fiber belongs to. - // Requires some refactoring. Not a big deal though since it's rare for - // concurrent apps to have more than a single root. - workInProgressRoot !== null && - (fiber.mode & BlockingMode) !== NoMode && // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps), - // then don't treat this as an interleaved update. This pattern is - // accompanied by a warning but we haven't fully deprecated it yet. We can - // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled. - deferRenderPhaseUpdateToNextBatch - ); } // Use this function to schedule a task for a root. There's only one task per // root; if a task was already scheduled, we'll check to make sure the priority // of the existing task is the same as the priority of the next level that the @@ -19074,36 +18031,22 @@ function ensureRootIsScheduled(root, currentTime) { // Special case: There's nothing to work on. if (existingCallbackNode !== null) { cancelCallback(existingCallbackNode); + root.callbackNode = null; + root.callbackPriority = NoLanePriority; } - root.callbackNode = null; - root.callbackPriority = NoLanePriority; return; } // Check if there's an existing task. We may be able to reuse it. - var existingCallbackPriority = root.callbackPriority; + if (existingCallbackNode !== null) { + var existingCallbackPriority = root.callbackPriority; - if (existingCallbackPriority === newCallbackPriority) { - { - // If we're going to re-use an existing task, it needs to exist. - // Assume that discrete update microtasks are non-cancellable and null. - // TODO: Temporary until we confirm this warning is not fired. - if ( - existingCallbackNode == null && - existingCallbackPriority !== InputDiscreteLanePriority && - existingCallbackPriority !== SyncLanePriority - ) { - error( - "Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue." - ); - } - } // The priority hasn't changed. We can reuse the existing task. Exit. - - return; - } + if (existingCallbackPriority === newCallbackPriority) { + // The priority hasn't changed. We can reuse the existing task. Exit. + return; + } // The priority changed. Cancel the existing callback. We'll schedule a new + // one below. - if (existingCallbackNode != null) { - // Cancel the existing callback. We'll schedule a new one below. cancelCallback(existingCallbackNode); } // Schedule a new callback. @@ -19112,11 +18055,12 @@ function ensureRootIsScheduled(root, currentTime) { if (newCallbackPriority === SyncLanePriority) { // Special case: Sync React callbacks are scheduled on a special // internal queue - scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root)); - newCallbackNode = null; + newCallbackNode = scheduleSyncCallback( + performSyncWorkOnRoot.bind(null, root) + ); } else if (newCallbackPriority === SyncBatchedLanePriority) { newCallbackNode = scheduleCallback( - ImmediatePriority, + ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root) ); } else { @@ -19134,11 +18078,12 @@ function ensureRootIsScheduled(root, currentTime) { } // This is the entry point for every concurrent task, i.e. anything that // goes through Scheduler. -function performConcurrentWorkOnRoot(root, didTimeout) { +function performConcurrentWorkOnRoot(root) { + // Since we know we're in a React event, we can clear the current // event time. The next update will compute a new event time. - currentEventTime = NoTimestamp; - currentEventTransitionLane = NoLanes; + currentEventWipLanes = NoLanes; + currentEventPendingLanes = NoLanes; if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) { throw Error("Should not already be working."); @@ -19168,22 +18113,24 @@ function performConcurrentWorkOnRoot(root, didTimeout) { if (lanes === NoLanes) { // Defensive coding. This is never expected to happen. return null; - } // TODO: We only check `didTimeout` defensively, to account for a Scheduler - // bug we're still investigating. Once the bug in Scheduler is fixed, - // we can remove this, since we track expiration ourselves. - - if (didTimeout) { - // Something expired. Flush synchronously until there's no expired - // work left. - markRootExpired(root, lanes); // This will schedule a synchronous callback. - - ensureRootIsScheduled(root, now()); - return null; } var exitStatus = renderRootConcurrent(root, lanes); - if (exitStatus !== RootIncomplete) { + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // So we'll throw out the current work and restart. + prepareFreshStack(root, NoLanes); + } else if (exitStatus !== RootIncomplete) { if (exitStatus === RootErrored) { executionContext |= RetryAfterError; // If an error occurred during hydration, // discard server response and fall back to client side render. @@ -19375,9 +18322,26 @@ function performSyncWorkOnRoot(root) { // rendering it before rendering the rest of the expired work. lanes = workInProgressRootRenderLanes; exitStatus = renderRootSync(root, lanes); - } else { - lanes = getNextLanes(root, NoLanes); // Because we don't cancel synchronous tasks, sometimes more than one + if ( + includesSomeLane( + workInProgressRootIncludedLanes, + workInProgressRootUpdatedLanes + ) + ) { + // The render included lanes that were updated during the render phase. + // For example, when unhiding a hidden tree, we include all the lanes + // that were previously skipped when the tree was hidden. That set of + // lanes is a superset of the lanes we started rendering with. + // + // Note that this only happens when part of the tree is rendered + // concurrently. If the whole tree is rendered synchronously, then there + // are no interleaved events. + lanes = getNextLanes(root, lanes); + exitStatus = renderRootSync(root, lanes); + } + } else { + lanes = getNextLanes(root, NoLanes); exitStatus = renderRootSync(root, lanes); } @@ -19455,7 +18419,7 @@ function flushSync(fn, a) { { try { if (fn) { - return runWithPriority(ImmediatePriority, fn.bind(null, a)); + return runWithPriority(ImmediatePriority$1, fn.bind(null, a)); } else { return undefined; } @@ -19511,7 +18475,6 @@ function prepareFreshStack(root, lanes) { workInProgressRootSkippedLanes = NoLanes; workInProgressRootUpdatedLanes = NoLanes; workInProgressRootPingedLanes = NoLanes; - enqueueInterleavedUpdates(); { spawnedWorkDuringRender = null; @@ -19835,6 +18798,47 @@ function completeUnitOfWork(unitOfWork) { workInProgress = next; return; } + + resetChildLanes(completedWork); + + if ( + returnFiber !== null && // Do not append effects to parents if a sibling failed to complete + (returnFiber.flags & Incomplete) === NoFlags + ) { + // Append all the effects of the subtree and this fiber onto the effect + // list of the parent. The completion order of the children affects the + // side-effect order. + if (returnFiber.firstEffect === null) { + returnFiber.firstEffect = completedWork.firstEffect; + } + + if (completedWork.lastEffect !== null) { + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = completedWork.firstEffect; + } + + returnFiber.lastEffect = completedWork.lastEffect; + } // If this fiber had side-effects, we append it AFTER the children's + // side-effects. We can perform certain side-effects earlier if needed, + // by doing multiple passes over the effect list. We don't want to + // schedule our own side-effect on our own list because if end up + // reusing children we'll schedule this effect onto itself since we're + // at the end. + + var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect + // list. PerformedWork effect is read by React DevTools but shouldn't be + // committed. + + if (flags > PerformedWork) { + if (returnFiber.lastEffect !== null) { + returnFiber.lastEffect.nextEffect = completedWork; + } else { + returnFiber.firstEffect = completedWork; + } + + returnFiber.lastEffect = completedWork; + } + } } else { // This fiber did not complete because something threw. Pop values off // the stack without entering the complete phase. If this is a boundary, @@ -19867,10 +18871,9 @@ function completeUnitOfWork(unitOfWork) { } if (returnFiber !== null) { - // Mark the parent fiber as incomplete and clear its subtree flags. + // Mark the parent fiber as incomplete and clear its effect list. + returnFiber.firstEffect = returnFiber.lastEffect = null; returnFiber.flags |= Incomplete; - returnFiber.subtreeFlags = NoFlags; - returnFiber.deletions = null; } } @@ -19892,10 +18895,88 @@ function completeUnitOfWork(unitOfWork) { } } +function resetChildLanes(completedWork) { + if ( + // TODO: Move this check out of the hot path by moving `resetChildLanes` + // to switch statement in `completeWork`. + (completedWork.tag === LegacyHiddenComponent || + completedWork.tag === OffscreenComponent) && + completedWork.memoizedState !== null && + !includesSomeLane(subtreeRenderLanes, OffscreenLane) && + (completedWork.mode & ConcurrentMode) !== NoLanes + ) { + // The children of this component are hidden. Don't bubble their + // expiration times. + return; + } + + var newChildLanes = NoLanes; // 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; // 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. + + var shouldBubbleActualDurations = + completedWork.alternate === null || + completedWork.child !== completedWork.alternate.child; + var child = completedWork.child; + + while (child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(child.lanes, child.childLanes) + ); + + if (shouldBubbleActualDurations) { + actualDuration += child.actualDuration; + } + + treeBaseDuration += child.treeBaseDuration; + child = child.sibling; + } + + var isTimedOutSuspense = + completedWork.tag === SuspenseComponent && + completedWork.memoizedState !== null; + + if (isTimedOutSuspense) { + // Don't count time spent in a timed out Suspense subtree as part of the base duration. + var primaryChildFragment = completedWork.child; + + if (primaryChildFragment !== null) { + treeBaseDuration -= primaryChildFragment.treeBaseDuration; + } + } + + completedWork.actualDuration = actualDuration; + completedWork.treeBaseDuration = treeBaseDuration; + } else { + var _child = completedWork.child; + + while (_child !== null) { + newChildLanes = mergeLanes( + newChildLanes, + mergeLanes(_child.lanes, _child.childLanes) + ); + _child = _child.sibling; + } + } + + completedWork.childLanes = newChildLanes; +} + function commitRoot(root) { var renderPriorityLevel = getCurrentPriorityLevel(); runWithPriority( - ImmediatePriority, + ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel) ); return null; @@ -19935,8 +19016,7 @@ function commitRootImpl(root, renderPriorityLevel) { } // commitRoot never returns a continuation; it always finishes synchronously. // So we can clear these now to allow a new callback to be scheduled. - root.callbackNode = null; - root.callbackPriority = NoLanePriority; // Update the first and last pending times on this root. The new first + root.callbackNode = null; // Update the first and last pending times on this root. The new first // pending time is whatever is left on the root fiber. var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes); @@ -19958,39 +19038,27 @@ function commitRootImpl(root, renderPriorityLevel) { workInProgressRoot = null; workInProgress = null; workInProgressRootRenderLanes = NoLanes; - } // If there are pending passive effects, schedule a callback to process them. - // Do this as early as possible, so it is queued before anything else that - // might get scheduled in the commit phase. (See #16714.) - // TODO: Delete all other places that schedule the passive effect callback - // They're redundant. - - if ( - (finishedWork.subtreeFlags & PassiveMask) !== NoFlags || - (finishedWork.flags & PassiveMask) !== NoFlags - ) { - if (!rootDoesHavePassiveEffects) { - rootDoesHavePassiveEffects = true; - scheduleCallback(NormalPriority, function() { - flushPassiveEffects(); - return null; - }); + } // Get the list of effects. + + var firstEffect; + + if (finishedWork.flags > PerformedWork) { + // A fiber's effect list consists only of its children, not itself. So if + // the root has an effect, we need to add it to the end of the list. The + // resulting list is the set that would belong to the root's parent, if it + // had one; that is, all the effects in the tree including the root. + if (finishedWork.lastEffect !== null) { + finishedWork.lastEffect.nextEffect = finishedWork; + firstEffect = finishedWork.firstEffect; + } else { + firstEffect = finishedWork; } - } // Check if there are any effects in the whole tree. - // TODO: This is left over from the effect list implementation, where we had - // to check for the existence of `firstEffect` to satsify Flow. I think the - // only other reason this optimization exists is because it affects profiling. - // Reconsider whether this is necessary. - - var subtreeHasEffects = - (finishedWork.subtreeFlags & - (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== - NoFlags; - var rootHasEffect = - (finishedWork.flags & - (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== - NoFlags; - - if (subtreeHasEffects || rootHasEffect) { + } else { + // There is no effect on the root. + firstEffect = finishedWork.firstEffect; + } + + if (firstEffect !== null) { var prevExecutionContext = executionContext; executionContext |= CommitContext; var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles @@ -20002,18 +19070,58 @@ function commitRootImpl(root, renderPriorityLevel) { // state of the host tree right before we mutate it. This is where // getSnapshotBeforeUpdate is called. - var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects( - root, - finishedWork - ); + focusedInstanceHandle = prepareForCommit(root.containerInfo); + shouldFireAfterActiveInstanceBlur = false; + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback(null, commitBeforeMutationEffects, null); + + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var error = clearCaughtError(); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); // We no longer need to track the active instance fiber + + focusedInstanceHandle = null; { // Mark the current commit time to be shared by all Profilers in this // batch. This enables them to be grouped later. recordCommitTime(); - } + } // The next phase is the mutation phase, where we mutate the host tree. + + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback( + null, + commitMutationEffects, + null, + root, + renderPriorityLevel + ); - commitMutationEffects(root, renderPriorityLevel, finishedWork); + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var _error = clearCaughtError(); + + captureCommitPhaseError(nextEffect, _error); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after // the mutation phase, so that the previous tree is still current during @@ -20021,8 +19129,29 @@ function commitRootImpl(root, renderPriorityLevel) { // work is current during componentDidMount/Update. root.current = finishedWork; // The next phase is the layout phase, where we call effects that read + // the host tree after it's been mutated. The idiomatic use case for this is + // layout, but class component lifecycles also fire here for legacy reasons. + + nextEffect = firstEffect; + + do { + { + invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes); + + if (hasCaughtError()) { + if (!(nextEffect !== null)) { + throw Error("Should be working on an effect."); + } + + var _error2 = clearCaughtError(); + + captureCommitPhaseError(nextEffect, _error2); + nextEffect = nextEffect.nextEffect; + } + } + } while (nextEffect !== null); - commitLayoutEffects(finishedWork, root, lanes); + nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an // opportunity to paint. requestPaint(); @@ -20052,6 +19181,22 @@ function commitRootImpl(root, renderPriorityLevel) { rootWithPendingPassiveEffects = root; pendingPassiveEffectsLanes = lanes; pendingPassiveEffectsRenderPriority = renderPriorityLevel; + } else { + // We are done with the effect chain at this point so let's clear the + // nextEffect pointers to assist with GC. If we have passive effects, we'll + // clear this in flushPassiveEffects. + nextEffect = firstEffect; + + while (nextEffect !== null) { + var nextNextEffect = nextEffect.nextEffect; + nextEffect.nextEffect = null; + + if (nextEffect.flags & Deletion) { + detachFiberAfterEffects(nextEffect); + } + + nextEffect = nextNextEffect; + } } // Read this again, since an effect might have updated it remainingLanes = root.pendingLanes; // Check if there's remaining work on this root @@ -20089,9 +19234,9 @@ function commitRootImpl(root, renderPriorityLevel) { } } - if (includesSomeLane(remainingLanes, SyncLane)) { + if (remainingLanes === SyncLane) { + // Count the number of times the root synchronously re-renders without // finishing. If there are too many, it indicates an infinite update loop. - if (root === rootWithNestedUpdates) { nestedUpdateCount++; } else { @@ -20109,9 +19254,9 @@ function commitRootImpl(root, renderPriorityLevel) { if (hasUncaughtError) { hasUncaughtError = false; - var error = firstUncaughtError; + var _error3 = firstUncaughtError; firstUncaughtError = null; - throw error; + throw _error3; } if ((executionContext & LegacyUnbatchedContext) !== NoContext) { @@ -20127,14 +19272,156 @@ function commitRootImpl(root, renderPriorityLevel) { return null; } +function commitBeforeMutationEffects() { + while (nextEffect !== null) { + var current = nextEffect.alternate; + + if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) { + if ((nextEffect.flags & Deletion) !== NoFlags) { + if (doesFiberContain(nextEffect, focusedInstanceHandle)) { + shouldFireAfterActiveInstanceBlur = true; + } + } else { + // TODO: Move this out of the hot path using a dedicated effect tag. + if ( + nextEffect.tag === SuspenseComponent && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) + ) { + shouldFireAfterActiveInstanceBlur = true; + } + } + } + + var flags = nextEffect.flags; + + if ((flags & Snapshot) !== NoFlags) { + setCurrentFiber(nextEffect); + commitBeforeMutationLifeCycles(current, nextEffect); + resetCurrentFiber(); + } + + if ((flags & Passive) !== NoFlags) { + // If there are passive effects, schedule a callback to flush at + // the earliest opportunity. + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } + } + + nextEffect = nextEffect.nextEffect; + } +} + +function commitMutationEffects(root, renderPriorityLevel) { + // TODO: Should probably move the bulk of this function to commitWork. + while (nextEffect !== null) { + setCurrentFiber(nextEffect); + var flags = nextEffect.flags; + + if (flags & ContentReset) { + commitResetTextContent(nextEffect); + } + + if (flags & Ref) { + var current = nextEffect.alternate; + + if (current !== null) { + commitDetachRef(current); + } + } // The following switch statement is only concerned about placement, + // updates, and deletions. To avoid needing to add a case for every possible + // bitmap value, we remove the secondary effects from the effect tag and + // switch on that value. + + var primaryFlags = flags & (Placement | Update | Deletion | Hydrating); + + switch (primaryFlags) { + case Placement: { + commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + // TODO: findDOMNode doesn't rely on this any more but isMounted does + // and isMounted is deprecated anyway so we should be able to kill this. + + nextEffect.flags &= ~Placement; + break; + } + + case PlacementAndUpdate: { + // Placement + commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is + // inserted, before any life-cycles like componentDidMount gets called. + + nextEffect.flags &= ~Placement; // Update + + var _current = nextEffect.alternate; + commitWork(_current, nextEffect); + break; + } + + case Hydrating: { + nextEffect.flags &= ~Hydrating; + break; + } + + case HydratingAndUpdate: { + nextEffect.flags &= ~Hydrating; // Update + + var _current2 = nextEffect.alternate; + commitWork(_current2, nextEffect); + break; + } + + case Update: { + var _current3 = nextEffect.alternate; + commitWork(_current3, nextEffect); + break; + } + + case Deletion: { + commitDeletion(root, nextEffect); + break; + } + } + + resetCurrentFiber(); + nextEffect = nextEffect.nextEffect; + } +} + +function commitLayoutEffects(root, committedLanes) { + while (nextEffect !== null) { + setCurrentFiber(nextEffect); + var flags = nextEffect.flags; + + if (flags & (Update | Callback)) { + var current = nextEffect.alternate; + commitLifeCycles(root, current, nextEffect); + } + + { + if (flags & Ref) { + commitAttachRef(nextEffect); + } + } + + resetCurrentFiber(); + nextEffect = nextEffect.nextEffect; + } +} + function flushPassiveEffects() { // Returns whether passive effects were flushed. - if (pendingPassiveEffectsRenderPriority !== NoPriority) { + if (pendingPassiveEffectsRenderPriority !== NoPriority$1) { var priorityLevel = - pendingPassiveEffectsRenderPriority > NormalPriority - ? NormalPriority + pendingPassiveEffectsRenderPriority > NormalPriority$1 + ? NormalPriority$1 : pendingPassiveEffectsRenderPriority; - pendingPassiveEffectsRenderPriority = NoPriority; + pendingPassiveEffectsRenderPriority = NoPriority$1; { return runWithPriority(priorityLevel, flushPassiveEffectsImpl); @@ -20143,6 +19430,42 @@ function flushPassiveEffects() { return false; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + + { + fiber.flags |= PassiveUnmountPendingDev; + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.flags |= PassiveUnmountPendingDev; + } + } + + if (!rootDoesHavePassiveEffects) { + rootDoesHavePassiveEffects = true; + scheduleCallback(NormalPriority$1, function() { + flushPassiveEffects(); + return null; + }); + } +} + +function invokePassiveEffectCreate(effect) { + var create = effect.create; + effect.destroy = create(); +} function flushPassiveEffectsImpl() { if (rootWithPendingPassiveEffects === null) { @@ -20164,9 +19487,97 @@ function flushPassiveEffectsImpl() { var prevExecutionContext = executionContext; executionContext |= CommitContext; - var prevInteractions = pushInteractions(root); - commitPassiveUnmountEffects(root.current); - commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects + var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called + // before ANY passive effect create functions are called. + // Otherwise effects in sibling components might interfere with each other. + // e.g. a destroy function in one component may unintentionally override a ref + // value set by a create function in another component. + // Layout effects have the same constraint. + // First pass: Destroy stale passive effects. + + var unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + + for (var i = 0; i < unmountEffects.length; i += 2) { + var _effect = unmountEffects[i]; + var fiber = unmountEffects[i + 1]; + var destroy = _effect.destroy; + _effect.destroy = undefined; + + { + fiber.flags &= ~PassiveUnmountPendingDev; + var alternate = fiber.alternate; + + if (alternate !== null) { + alternate.flags &= ~PassiveUnmountPendingDev; + } + } + + if (typeof destroy === "function") { + { + setCurrentFiber(fiber); + + { + invokeGuardedCallback(null, destroy, null); + } + + if (hasCaughtError()) { + if (!(fiber !== null)) { + throw Error("Should be working on an effect."); + } + + var error = clearCaughtError(); + captureCommitPhaseError(fiber, error); + } + + resetCurrentFiber(); + } + } + } // Second pass: Create new passive effects. + + var mountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + + for (var _i = 0; _i < mountEffects.length; _i += 2) { + var _effect2 = mountEffects[_i]; + var _fiber = mountEffects[_i + 1]; + + { + setCurrentFiber(_fiber); + + { + invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2); + } + + if (hasCaughtError()) { + if (!(_fiber !== null)) { + throw Error("Should be working on an effect."); + } + + var _error4 = clearCaughtError(); + + captureCommitPhaseError(_fiber, _error4); + } + + resetCurrentFiber(); + } + } // Note: This currently assumes there are no passive effects on the root fiber + // because the root is not part of its own effect list. + // This could change in the future. + + var effect = root.current.firstEffect; + + while (effect !== null) { + var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC + + effect.nextEffect = null; + + if (effect.flags & Deletion) { + detachFiberAfterEffects(effect); + } + + effect = nextNextEffect; + } { popInteractions(prevInteractions); @@ -20223,23 +19634,19 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { } } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { +function captureCommitPhaseError(sourceFiber, error) { if (sourceFiber.tag === HostRoot) { // Error was thrown at the root. There is no parent, so the root // itself should capture it. - captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1); + captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); return; } - var fiber = null; - - { - fiber = sourceFiber.return; - } + var fiber = sourceFiber.return; while (fiber !== null) { if (fiber.tag === HostRoot) { - captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1); + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); return; } else if (fiber.tag === ClassComponent) { var ctor = fiber.type; @@ -20250,7 +19657,7 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { (typeof instance.componentDidCatch === "function" && !isAlreadyFailedLegacyErrorBoundary(instance)) ) { - var errorInfo = createCapturedValue(error$1, sourceFiber); + var errorInfo = createCapturedValue(error, sourceFiber); var update = createClassErrorUpdate(fiber, errorInfo, SyncLane); enqueueUpdate(fiber, update); var eventTime = requestEventTime(); @@ -20260,6 +19667,24 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { markRootUpdated(root, SyncLane, eventTime); ensureRootIsScheduled(root, eventTime); schedulePendingInteractions(root, SyncLane); + } else { + // This component has already been unmounted. + // We can't schedule any follow up work for the root because the fiber is already unmounted, + // but we can still call the log-only boundary so the error isn't swallowed. + // + // TODO This is only a temporary bandaid for the old reconciler fork. + // We can delete this special case once the new fork is merged. + if ( + typeof instance.componentDidCatch === "function" && + !isAlreadyFailedLegacyErrorBoundary(instance) + ) { + try { + instance.componentDidCatch(error, errorInfo); + } catch (errorToIgnore) { + // TODO Ignore this error? Rethrow it? + // This is kind of an edge case. + } + } } return; @@ -20268,22 +19693,6 @@ function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) { fiber = fiber.return; } - - { - // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning - // will fire for errors that are thrown by destroy functions inside deleted - // trees. What it should instead do is propagate the error to the parent of - // the deleted tree. In the meantime, do not add this warning to the - // allowlist; this is only for our internal use. - error( - "Internal React error: Attempted to capture a commit phase error " + - "inside a detached tree. This indicates a bug in React. Likely " + - "causes include deleting the same fiber more than once, committing an " + - "already-finished tree, or an inconsistent return pointer.\n\n" + - "Error message:\n\n%s", - error$1 - ); - } } function pingSuspendedRoot(root, wakeable, pingedLanes) { var pingCache = root.pingCache; @@ -20336,8 +19745,6 @@ function retryTimedOutBoundary(boundaryFiber, retryLane) { // suspended it has resolved, which means at least part of the tree was // likely unblocked. Try rendering again, at a new expiration time. if (retryLane === NoLane) { - // TODO: Assign this to `suspenseState.retryLane`? to avoid - // unnecessary entanglement? retryLane = requestRetryLane(boundaryFiber); } // TODO: Special case idle priority? @@ -20506,29 +19913,11 @@ function warnAboutUpdateOnUnmountedFiberInDEV(fiber) { ) { // Only warn for user-defined components, not internal ones like Suspense. return; - } - - if ((fiber.flags & PassiveStatic) !== NoFlags) { - var updateQueue = fiber.updateQueue; - - if (updateQueue !== null) { - var lastEffect = updateQueue.lastEffect; - - if (lastEffect !== null) { - var firstEffect = lastEffect.next; - var effect = firstEffect; - - do { - if (effect.destroy !== undefined) { - if ((effect.tag & Passive$1) !== NoFlags$1) { - return; - } - } + } // If there are pending passive effects unmounts for this Fiber, + // we can assume that they would have prevented this update. - effect = effect.next; - } while (effect !== firstEffect); - } - } + if ((fiber.flags & PassiveUnmountPendingDev) !== NoFlags) { + return; } // We show the whole stack but dedupe on the top component's name because // the problematic code almost always lies inside that component. @@ -20616,23 +20005,14 @@ var beginWork$1; invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes); if (hasCaughtError()) { - var replayError = clearCaughtError(); + var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`. + // Rethrow this error instead of the original one. - if ( - typeof replayError === "object" && - replayError !== null && - replayError._suppressLogging && - typeof originalError === "object" && - originalError !== null && - !originalError._suppressLogging - ) { - // If suppressed, let the flag carry over to the original error which is the one we'll rethrow. - originalError._suppressLogging = true; - } - } // We always throw the original error in case the second render pass is not idempotent. - // This can happen if a memoized function or CommonJS module doesn't throw after first invokation. - - throw originalError; + throw replayError; + } else { + // This branch is reachable if the render phase is impure. + throw originalError; + } } }; } @@ -20721,7 +20101,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { "act(() => ...);\n\n" + "// for react-test-renderer:\n" + // Break up imports to avoid accidentally parsing them as dependencies. "import TestRenderer fr" + - "om 'react-test-renderer';\n" + + "om react-test-renderer';\n" + "const {act} = TestRenderer;\n" + "// ...\n" + "act(() => ...);" @@ -20739,7 +20119,7 @@ function warnIfNotScopedWithMatchingAct(fiber) { function warnIfNotCurrentlyActingEffectsInDEV(fiber) { { if ( - (fiber.mode & StrictLegacyMode) !== NoMode && + (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false ) { @@ -20919,7 +20299,7 @@ function startWorkOnPendingInteractions(root, lanes) { subscriber.onWorkStarted(interactions, threadID); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } @@ -20941,7 +20321,7 @@ function finishPendingInteractions(root, committedLanes) { } } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } finally { @@ -20963,7 +20343,7 @@ function finishPendingInteractions(root, committedLanes) { subscriber.onInteractionScheduledWorkCompleted(interaction); } catch (error) { // If the subscriber throws, rethrow it in a separate task - scheduleCallback(ImmediatePriority, function() { + scheduleCallback(ImmediatePriority$1, function() { throw error; }); } @@ -20982,6 +20362,11 @@ function shouldForceFlushFallbacksInDEV() { var actingUpdatesScopeDepth = 0; +function detachFiberAfterEffects(fiber) { + fiber.sibling = null; + fiber.stateNode = null; +} + var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below. var failedBoundaries = null; @@ -21458,8 +20843,9 @@ function FiberNode(tag, pendingProps, key, mode) { this.mode = mode; // Effects this.flags = NoFlags; - this.subtreeFlags = NoFlags; - this.deletions = null; + this.nextEffect = null; + this.firstEffect = null; + this.lastEffect = null; this.lanes = NoLanes; this.childLanes = NoLanes; this.alternate = null; @@ -21586,10 +20972,11 @@ function createWorkInProgress(current, pendingProps) { workInProgress.type = current.type; // We already have an alternate. // Reset the effect tag. - workInProgress.flags = NoFlags; // The effects are no longer valid. + workInProgress.flags = NoFlags; // The effect list is no longer valid. - workInProgress.subtreeFlags = NoFlags; - workInProgress.deletions = null; + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; { // We intentionally reset, rather than copy, actualDuration & actualStartTime. @@ -21599,10 +20986,8 @@ function createWorkInProgress(current, pendingProps) { workInProgress.actualDuration = 0; workInProgress.actualStartTime = -1; } - } // Reset all effects except static ones. - // Static effects are not specific to a render. + } - workInProgress.flags = current.flags & StaticMask; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -21659,10 +21044,13 @@ function resetWorkInProgress(workInProgress, renderLanes) { // when they should be reading from current and writing to workInProgress. // We assume pendingProps, index, key, ref, return are still untouched to // avoid doing another reconciliation. - // Reset the effect flags but keep any Placement tags, since that's something + // Reset the effect tag but keep any Placement tags, since that's something // that child fiber is setting, not the reconciliation. - workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid. + workInProgress.flags &= Placement; // The effect list is no longer valid. + workInProgress.nextEffect = null; + workInProgress.firstEffect = null; + workInProgress.lastEffect = null; var current = workInProgress.alternate; if (current === null) { @@ -21670,7 +21058,6 @@ function resetWorkInProgress(workInProgress, renderLanes) { workInProgress.childLanes = NoLanes; workInProgress.lanes = renderLanes; workInProgress.child = null; - workInProgress.subtreeFlags = NoFlags; workInProgress.memoizedProps = null; workInProgress.memoizedState = null; workInProgress.updateQueue = null; @@ -21687,12 +21074,7 @@ function resetWorkInProgress(workInProgress, renderLanes) { // Reset to the cloned values that createWorkInProgress would've. workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; - workInProgress.child = current.child; // TODO: `subtreeFlags` should be reset to NoFlags, like we do in - // `createWorkInProgress`. Nothing reads this until the complete phase, - // currently, but it might in the future, and we should be consistent. - - workInProgress.subtreeFlags = current.subtreeFlags; - workInProgress.deletions = null; + workInProgress.child = current.child; workInProgress.memoizedProps = current.memoizedProps; workInProgress.memoizedState = current.memoizedState; workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type. @@ -21719,33 +21101,13 @@ function resetWorkInProgress(workInProgress, renderLanes) { return workInProgress; } -function createHostRootFiber(tag, strictModeLevelOverride) { +function createHostRootFiber(tag) { var mode; if (tag === ConcurrentRoot) { - mode = ConcurrentMode | BlockingMode; - - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { - { - mode |= StrictLegacyMode; - } - } + mode = ConcurrentMode | BlockingMode | StrictMode; } else if (tag === BlockingRoot) { - mode = BlockingMode; - - if (strictModeLevelOverride !== null) { - if (strictModeLevelOverride >= 1) { - mode |= StrictLegacyMode; - } - } else { - { - mode |= StrictLegacyMode; - } - } + mode = BlockingMode | StrictMode; } else { mode = NoMode; } @@ -21796,16 +21158,8 @@ function createFiberFromTypeAndProps( break; case REACT_STRICT_MODE_TYPE: - fiberTag = Mode; // Legacy strict mode ( without any level prop) defaults to level 1. - - var level = - pendingProps.unstable_level == null ? 1 : pendingProps.unstable_level; // Levels cascade; higher levels inherit all lower level modes. - // It is explicitly not supported to lower a mode with nesting, only to increase it. - - if (level >= 1) { - mode |= StrictLegacyMode; - } - + fiberTag = Mode; + mode |= StrictMode; break; case REACT_PROFILER_TYPE: @@ -21827,10 +21181,6 @@ function createFiberFromTypeAndProps( // eslint-disable-next-line no-fallthrough - case REACT_CACHE_TYPE: - - // eslint-disable-next-line no-fallthrough - default: { if (typeof type === "object" && type !== null) { switch (type.$$typeof) { @@ -22059,8 +21409,9 @@ function assignFiberPropertiesInDEV(target, source) { target.dependencies = source.dependencies; target.mode = source.mode; target.flags = source.flags; - target.subtreeFlags = source.subtreeFlags; - target.deletions = source.deletions; + target.nextEffect = source.nextEffect; + target.firstEffect = source.firstEffect; + target.lastEffect = source.lastEffect; target.lanes = source.lanes; target.childLanes = source.childLanes; target.alternate = source.alternate; @@ -22127,27 +21478,13 @@ function FiberRootNode(containerInfo, tag, hydrate) { } } -function createFiberRoot( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride -) { +function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) { var root = new FiberRootNode(containerInfo, tag, hydrate); // stateNode is any. - var uninitializedFiber = createHostRootFiber(tag, strictModeLevelOverride); + var uninitializedFiber = createHostRootFiber(tag); root.current = uninitializedFiber; uninitializedFiber.stateNode = root; - - { - var _initialState = { - element: null - }; - uninitializedFiber.memoizedState = _initialState; - } - initializeUpdateQueue(uninitializedFiber); return root; } @@ -22221,7 +21558,7 @@ function findHostInstanceWithWarning(component, methodName) { return null; } - if (hostFiber.mode & StrictLegacyMode) { + if (hostFiber.mode & StrictMode) { var componentName = getComponentName(fiber.type) || "Component"; if (!didWarnAboutFindNodeInStrictMode[componentName]) { @@ -22231,7 +21568,7 @@ function findHostInstanceWithWarning(component, methodName) { try { setCurrentFiber(hostFiber); - if (fiber.mode & StrictLegacyMode) { + if (fiber.mode & StrictMode) { error( "%s is deprecated in StrictMode. " + "%s was passed an instance of %s which is inside StrictMode. " + @@ -22270,20 +21607,8 @@ function findHostInstanceWithWarning(component, methodName) { } } -function createContainer( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride -) { - return createFiberRoot( - containerInfo, - tag, - hydrate, - hydrationCallbacks, - strictModeLevelOverride - ); +function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) { + return createFiberRoot(containerInfo, tag, hydrate); } function updateContainer(element, container, parentComponent, callback) { { @@ -22348,12 +21673,7 @@ function updateContainer(element, container, parentComponent, callback) { } enqueueUpdate(current$1, update); - var root = scheduleUpdateOnFiber(current$1, lane, eventTime); - - if (root !== null) { - entangleTransitions(root, current$1, lane); - } - + scheduleUpdateOnFiber(current$1, lane, eventTime); return lane; } function getPublicRootInstance(container) { @@ -23034,12 +22354,11 @@ function render(element, containerTag, callback) { if (!root) { // TODO (bvaughn): If we decide to keep the wrapper component, // We could create a wrapper for containerTag as well to reduce special casing. - root = createContainer(containerTag, LegacyRoot, false, null, null); + root = createContainer(containerTag, LegacyRoot, false); roots.set(containerTag, root); } - updateContainer(element, root, null, callback); // $FlowIssue Flow has hardcoded values for React DOM that don't work with RN - + updateContainer(element, root, null, callback); return getPublicRootInstance(root); } diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index 8d91437ab93175..ccced617800599 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -919,7 +919,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_213 = { +var injectedNamesToPlugins$jscomp$inline_222 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -954,34 +954,34 @@ var injectedNamesToPlugins$jscomp$inline_213 = { } } }, - isOrderingDirty$jscomp$inline_214 = !1, - pluginName$jscomp$inline_215; -for (pluginName$jscomp$inline_215 in injectedNamesToPlugins$jscomp$inline_213) + isOrderingDirty$jscomp$inline_223 = !1, + pluginName$jscomp$inline_224; +for (pluginName$jscomp$inline_224 in injectedNamesToPlugins$jscomp$inline_222) if ( - injectedNamesToPlugins$jscomp$inline_213.hasOwnProperty( - pluginName$jscomp$inline_215 + injectedNamesToPlugins$jscomp$inline_222.hasOwnProperty( + pluginName$jscomp$inline_224 ) ) { - var pluginModule$jscomp$inline_216 = - injectedNamesToPlugins$jscomp$inline_213[pluginName$jscomp$inline_215]; + var pluginModule$jscomp$inline_225 = + injectedNamesToPlugins$jscomp$inline_222[pluginName$jscomp$inline_224]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_215) || - namesToPlugins[pluginName$jscomp$inline_215] !== - pluginModule$jscomp$inline_216 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_224) || + namesToPlugins[pluginName$jscomp$inline_224] !== + pluginModule$jscomp$inline_225 ) { - if (namesToPlugins[pluginName$jscomp$inline_215]) + if (namesToPlugins[pluginName$jscomp$inline_224]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_215 + + pluginName$jscomp$inline_224 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_215 - ] = pluginModule$jscomp$inline_216; - isOrderingDirty$jscomp$inline_214 = !0; + pluginName$jscomp$inline_224 + ] = pluginModule$jscomp$inline_225; + isOrderingDirty$jscomp$inline_223 = !0; } } -isOrderingDirty$jscomp$inline_214 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_223 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1139,8 +1139,7 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131, - REACT_CACHE_TYPE = 60132; + REACT_LEGACY_HIDDEN_TYPE = 60131; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1159,7 +1158,6 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1186,8 +1184,6 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - case REACT_CACHE_TYPE: - return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1221,7 +1217,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 2050) && (nearestMounted = node.return), + 0 !== (node.flags & 1026) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1309,14 +1305,19 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; -} -function findCurrentHostFiberImpl(node) { - if (5 === node.tag || 6 === node.tag) return node; - for (node = node.child; null !== node; ) { - var match = findCurrentHostFiberImpl(node); - if (null !== match) return match; - node = node.sibling; + if (!parent) return null; + for (var node = parent; ; ) { + if (5 === node.tag || 6 === node.tag) return node; + if (node.child) (node.child.return = node), (node = node.child); + else { + if (node === parent) break; + for (; !node.sibling; ) { + if (!node.return || node.return === parent) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } return null; } @@ -1566,382 +1567,60 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) - ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( - this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( - this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps - ); - }; - return ReactNativeFiberHostComponent; - })(), - Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, - requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs = Scheduler_now(), - now = - 1e4 > initialTimeMs - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } -} -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); - } -} -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); -} -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); -} -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); -} -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } -} -var nextTransitionLane = 512, - nextRetryLane = 8388608, - return_highestLanePriority = 8; -function getHighestPriorityLanes(lanes) { - switch (lanes & -lanes) { - case 1: - return (return_highestLanePriority = 15), 1; - case 2: - return (return_highestLanePriority = 14), 2; - case 4: - return (return_highestLanePriority = 13), 4; - case 8: - return (return_highestLanePriority = 12), 8; - case 16: - return (return_highestLanePriority = 11), 16; - case 32: - return (return_highestLanePriority = 10), 32; - case 64: - return (return_highestLanePriority = 9), 64; - case 128: - return (return_highestLanePriority = 8), 128; - case 256: - return (return_highestLanePriority = 7), 256; - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - return (return_highestLanePriority = 6), lanes & 8388096; - case 8388608: - case 16777216: - case 33554432: - case 67108864: - return (return_highestLanePriority = 5), lanes & 125829120; - case 134217728: - return (return_highestLanePriority = 4), 134217728; - case 268435456: - return (return_highestLanePriority = 3), 268435456; - case 536870912: - return (return_highestLanePriority = 2), 536870912; - case 1073741824: - return (return_highestLanePriority = 1), 1073741824; - default: - return (return_highestLanePriority = 8), lanes; - } -} -function schedulerPriorityToLanePriority(schedulerPriorityLevel) { - switch (schedulerPriorityLevel) { - case 99: - return 15; - case 98: - return 10; - case 97: - case 96: - return 8; - case 95: - return 2; - default: - return 0; - } -} -function lanePriorityToSchedulerPriority(lanePriority) { - switch (lanePriority) { - case 15: - case 14: - return 99; - case 13: - case 12: - case 11: - case 10: - return 98; - case 9: - case 8: - case 7: - case 6: - case 4: - case 5: - return 97; - case 3: - case 2: - case 1: - return 95; - case 0: - return 90; - default: - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." + this.viewConfig.uiViewClassName, + nativeProps ); - } -} -function getNextLanes(root, wipLanes) { - var pendingLanes = root.pendingLanes; - if (0 === pendingLanes) return (return_highestLanePriority = 0); - var nextLanes = 0, - nextLanePriority = 0, - expiredLanes = root.expiredLanes, - suspendedLanes = root.suspendedLanes, - pingedLanes = root.pingedLanes; - 0 !== expiredLanes - ? ((nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15)) - : ((expiredLanes = pendingLanes & 268435455), - 0 !== expiredLanes - ? ((pendingLanes = expiredLanes & ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))); - if (0 === nextLanes) return 0; - if ( - 0 !== wipLanes && - wipLanes !== nextLanes && - 0 === (wipLanes & suspendedLanes) - ) { - getHighestPriorityLanes(wipLanes); - suspendedLanes = return_highestLanePriority; - if ( - nextLanePriority <= suspendedLanes || - (8 === nextLanePriority && 6 === suspendedLanes) - ) - return wipLanes; - return_highestLanePriority = nextLanePriority; - } - wipLanes = root.entangledLanes; - if (0 !== wipLanes) - for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (nextLanePriority = 31 - clz32(wipLanes)), - (suspendedLanes = 1 << nextLanePriority), - (nextLanes |= root[nextLanePriority]), - (wipLanes &= ~suspendedLanes); - return nextLanes; -} -function getLanesToRetrySynchronouslyOnError(root) { - root = root.pendingLanes & -1073741825; - return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; -} -function findUpdateLane(lanePriority) { - switch (lanePriority) { - case 15: - return 1; - case 14: - return 2; - case 12: - return 8; - case 10: - return 32; - case 8: - return 128; - case 2: - return 536870912; - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - remainingLanes = root.entanglements; - var eventTimes = root.eventTimes; - for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { - var index$8 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$8; - remainingLanes[index$8] = 0; - eventTimes[index$8] = -1; - root[index$8] = -1; - noLongerPendingLanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index$9 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$9; - (lane & entangledLanes) | (root[index$9] & entangledLanes) && - (root[index$9] |= entangledLanes); - rootEntangledLanes &= ~lane; - } -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_now$1 = Scheduler.unstable_now; -Scheduler_now$1(); + }; + return ReactNativeFiberHostComponent; +})(); function shim() { throw Error( "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." @@ -2087,17 +1766,296 @@ function invalidateContextProvider(workInProgress, type, didChange) { push(didPerformWorkStackCursor, didChange); } var rendererID = null, - injectedHook = null; -function onCommitRoot(root) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) - try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - void 0, - 128 === (root.current.flags & 128) + injectedHook = null, + Scheduler_now = Scheduler.unstable_now; +Scheduler_now(); +var return_highestLanePriority = 8; +function getHighestPriorityLanes(lanes) { + if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; + if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; + if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; + var inputDiscreteLanes = 24 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 12), inputDiscreteLanes; + if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; + inputDiscreteLanes = 192 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 10), inputDiscreteLanes; + if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; + inputDiscreteLanes = 3584 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 8), inputDiscreteLanes; + if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; + inputDiscreteLanes = 4186112 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 6), inputDiscreteLanes; + inputDiscreteLanes = 62914560 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 5), inputDiscreteLanes; + if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; + if (0 !== (lanes & 134217728)) + return (return_highestLanePriority = 3), 134217728; + inputDiscreteLanes = 805306368 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 2), inputDiscreteLanes; + if (0 !== (1073741824 & lanes)) + return (return_highestLanePriority = 1), 1073741824; + return_highestLanePriority = 8; + return lanes; +} +function schedulerPriorityToLanePriority(schedulerPriorityLevel) { + switch (schedulerPriorityLevel) { + case 99: + return 15; + case 98: + return 10; + case 97: + case 96: + return 8; + case 95: + return 2; + default: + return 0; + } +} +function lanePriorityToSchedulerPriority(lanePriority) { + switch (lanePriority) { + case 15: + case 14: + return 99; + case 13: + case 12: + case 11: + case 10: + return 98; + case 9: + case 8: + case 7: + case 6: + case 4: + case 5: + return 97; + case 3: + case 2: + case 1: + return 95; + case 0: + return 90; + default: + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." ); - } catch (err) {} + } +} +function getNextLanes(root, wipLanes) { + var pendingLanes = root.pendingLanes; + if (0 === pendingLanes) return (return_highestLanePriority = 0); + var nextLanes = 0, + nextLanePriority = 0, + expiredLanes = root.expiredLanes, + suspendedLanes = root.suspendedLanes, + pingedLanes = root.pingedLanes; + if (0 !== expiredLanes) + (nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15); + else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { + var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority))); + } else + (expiredLanes = pendingLanes & ~suspendedLanes), + 0 !== expiredLanes + ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)); + if (0 === nextLanes) return 0; + nextLanes = 31 - clz32(nextLanes); + nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); + if ( + 0 !== wipLanes && + wipLanes !== nextLanes && + 0 === (wipLanes & suspendedLanes) + ) { + getHighestPriorityLanes(wipLanes); + if (nextLanePriority <= return_highestLanePriority) return wipLanes; + return_highestLanePriority = nextLanePriority; + } + wipLanes = root.entangledLanes; + if (0 !== wipLanes) + for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) + (pendingLanes = 31 - clz32(wipLanes)), + (nextLanePriority = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~nextLanePriority); + return nextLanes; +} +function getLanesToRetrySynchronouslyOnError(root) { + root = root.pendingLanes & -1073741825; + return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; +} +function findUpdateLane(lanePriority, wipLanes) { + switch (lanePriority) { + case 15: + return 1; + case 14: + return 2; + case 12: + return ( + (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority + ); + case 10: + return ( + (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority + ); + case 8: + return ( + (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), + 0 === lanePriority && + ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), + 0 === lanePriority && (lanePriority = 512)), + lanePriority + ); + case 2: + return ( + (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), + 0 === wipLanes && (wipLanes = 268435456), + wipLanes + ); + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." + ); +} +function getHighestPriorityLane(lanes) { + return lanes & -lanes; +} +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; +} +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + var higherPriorityLanes = updateLane - 1; + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; +} +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; +} +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority, + fakeCallbackNode = {}, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs$1 = Scheduler_now$1(), + now = + 1e4 > initialTimeMs$1 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } +} +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } +} +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); +} +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +} +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); +} +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; + try { + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2177,10 +2135,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(context) { +function popProvider(providerFiber) { var currentValue = valueCursor.current; pop(valueCursor); - context._currentValue = currentValue; + providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2231,14 +2189,13 @@ function readContext(context, observedBits) { } return context._currentValue; } -var interleavedQueues = null, - hasForceUpdate = !1; +var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null, interleaved: null, lanes: 0 }, + shared: { pending: null }, effects: null }; } @@ -2264,32 +2221,14 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - null !== updateQueue && - ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && 0 !== (fiber.mode & 1) - ? ((fiber = updateQueue.interleaved), - null === fiber - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [updateQueue]) - : interleavedQueues.push(updateQueue)) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.interleaved = update)) - : ((fiber = updateQueue.pending), - null === fiber - ? (update.next = update) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.pending = update))); -} -function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2358,110 +2297,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue + if (null !== current) { + current = current.updateQueue; + var currentLastBaseUpdate = current.lastBaseUpdate; + currentLastBaseUpdate !== lastBaseUpdate && + (null === currentLastBaseUpdate ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); + : (currentLastBaseUpdate.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate)); + } } if (null !== firstBaseUpdate) { - var newState = queue.baseState; + currentLastBaseUpdate = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; do { - var updateLane = pendingQueue.lane, - updateEventTime = pendingQueue.eventTime; - if ((renderLanes & updateLane) === updateLane) { + pendingQueue = firstBaseUpdate.lane; + var updateEventTime = firstBaseUpdate.eventTime; + if ((renderLanes & pendingQueue) === pendingQueue) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = pendingQueue; - updateLane = props; + update = firstBaseUpdate; + pendingQueue = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - newState = workInProgress.call( + currentLastBaseUpdate = workInProgress.call( updateEventTime, - newState, - updateLane + currentLastBaseUpdate, + pendingQueue ); break a; } - newState = workInProgress; + currentLastBaseUpdate = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -16385) | 128; + workInProgress.flags = (workInProgress.flags & -8193) | 64; case 0: workInProgress = update.payload; - updateLane = + pendingQueue = "function" === typeof workInProgress - ? workInProgress.call(updateEventTime, newState, updateLane) + ? workInProgress.call( + updateEventTime, + currentLastBaseUpdate, + pendingQueue + ) : workInProgress; - if (null === updateLane || void 0 === updateLane) break a; - newState = Object.assign({}, newState, updateLane); + if (null === pendingQueue || void 0 === pendingQueue) break a; + currentLastBaseUpdate = Object.assign( + {}, + currentLastBaseUpdate, + pendingQueue + ); break a; case 2: hasForceUpdate = !0; } } - null !== pendingQueue.callback && - ((workInProgress$jscomp$0.flags |= 64), - (updateLane = queue.effects), - null === updateLane - ? (queue.effects = [pendingQueue]) - : updateLane.push(pendingQueue)); + null !== firstBaseUpdate.callback && + ((workInProgress$jscomp$0.flags |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [firstBaseUpdate]) + : pendingQueue.push(firstBaseUpdate)); } else (updateEventTime = { eventTime: updateEventTime, - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + lane: pendingQueue, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = newState)) + (lastPendingUpdate = currentLastBaseUpdate)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) + (lastBaseUpdate |= pendingQueue); + firstBaseUpdate = firstBaseUpdate.next; + if (null === firstBaseUpdate) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (updateLane = pendingQueue), - (pendingQueue = updateLane.next), - (updateLane.next = null), - (queue.lastBaseUpdate = updateLane), + (firstBaseUpdate = pendingQueue.next), + (pendingQueue.next = null), + (queue.lastBaseUpdate = pendingQueue), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = newState); + null === current && (lastPendingUpdate = currentLastBaseUpdate); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; - props = queue.shared.interleaved; - if (null !== props) { - queue = props; - do (lastBaseUpdate |= queue.lane), (queue = queue.next); - while (queue !== props); - } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = newState; + workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2517,8 +2457,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2529,8 +2468,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2540,8 +2478,7 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - callback = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== callback && entangleTransitions(callback, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); } }; function checkShouldComponentUpdate( @@ -2689,22 +2626,24 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( + throw Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber + ("[object Object]" === Object.prototype.toString.call(newChild) ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + + : newChild) + "). If you meant to render a collection of children, use an array instead." - )); + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) - : deletions.push(childToDelete); + var last = returnFiber.lastEffect; + null !== last + ? ((last.nextEffect = childToDelete), + (returnFiber.lastEffect = childToDelete)) + : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); + childToDelete.nextEffect = null; + childToDelete.flags = 8; } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2736,16 +2675,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags |= 2), lastPlacedIndex) + ? ((newFiber.flags = 2), lastPlacedIndex) : newIndex ); - newFiber.flags |= 2; + newFiber.flags = 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags |= 2); + (newFiber.flags = 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2760,16 +2699,7 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - if (null !== current && current.elementType === elementType) + if (null !== current && current.elementType === element.type) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2883,7 +2813,15 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? updateElement(returnFiber, oldFiber, newChild, lanes) + ? newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ) + : updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2918,7 +2856,15 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - updateElement(returnFiber, existingChildren, newChild, lanes) + newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + existingChildren, + newChild.props.children, + lanes, + newChild.key + ) + : updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3114,48 +3060,53 @@ function ChildReconciler(shouldTrackSideEffects) { isUnkeyedTopLevelFragment && (newChild = newChild.props.children); var isObject = "object" === typeof newChild && null !== newChild; if (isObject) - switch (newChild.$$typeof) { - case REACT_ELEMENT_TYPE: - a: { - isObject = newChild.key; - for ( - isUnkeyedTopLevelFragment = currentFirstChild; - null !== isUnkeyedTopLevelFragment; - - ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { - if (7 === isUnkeyedTopLevelFragment.tag) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; + switch (newChild.$$typeof) { + case REACT_ELEMENT_TYPE: + a: { + isObject = newChild.key; + for ( + isUnkeyedTopLevelFragment = currentFirstChild; + null !== isUnkeyedTopLevelFragment; + + ) { + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3333,7 +3284,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 128)) return node; + if (0 !== (node.flags & 64)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3485,11 +3436,10 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - pendingQueue = baseQueue.next; + baseQueue = baseQueue.next; current = current.baseState; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = pendingQueue; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3514,33 +3464,22 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (baseFirst = current)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== pendingQueue); + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (baseFirst = current) - : (newBaseQueueLast.next = newBaseQueueFirst); + ? (pendingQueue = current) + : (newBaseQueueLast.next = baseFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = baseFirst; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } - reducer = queue.interleaved; - if (null !== reducer) { - baseQueue = reducer; - do - (pendingQueue = baseQueue.lane), - (currentlyRenderingFiber$1.lanes |= pendingQueue), - (workInProgressRootSkippedLanes |= pendingQueue), - (baseQueue = baseQueue.next); - while (baseQueue !== reducer); - } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3580,7 +3519,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3610,13 +3549,25 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - objectIs(version, maybeNewVersion) || - ((maybeNewVersion = getSnapshot(source._source)), + if (!objectIs(version, maybeNewVersion)) { + maybeNewVersion = getSnapshot(source._source); objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), - markRootEntangled(root, root.mutableReadLanes)); + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); + maybeNewVersion = root.mutableReadLanes; + root.entangledLanes |= maybeNewVersion; + for ( + var entanglements = root.entanglements, lanes = maybeNewVersion; + 0 < lanes; + + ) { + var index$13 = 31 - clz32(lanes), + lane = 1 << index$13; + entanglements[index$13] |= maybeNewVersion; + lanes &= ~lane; + } + } }, [getSnapshot, source, subscribe] ); @@ -3643,8 +3594,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3670,8 +3619,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3720,7 +3667,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); + pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3728,10 +3675,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(132096, 4, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(1024, 4, create, deps); + return updateEffectImpl(516, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3816,55 +3763,33 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - alternate = fiber.alternate; + pending = queue.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + queue.pending = update; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), - (lane = queue.pending), - null === lane - ? (update.next = update) - : ((update.next = lane.next), (lane.next = update)), - (queue.pending = update); + didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; else { - if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { - var interleaved = queue.interleaved; - null === interleaved - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [queue]) - : interleavedQueues.push(queue)) - : ((update.next = interleaved.next), (interleaved.next = update)); - queue.interleaved = update; - } else - (interleaved = queue.pending), - null === interleaved - ? (update.next = update) - : ((update.next = interleaved.next), (interleaved.next = update)), - (queue.pending = update); if ( 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.lanes) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.eagerReducer = alternate; + eagerState = pending(currentState, action); + update.eagerReducer = pending; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - update = scheduleUpdateOnFiber(fiber, lane, eventTime); - 0 !== (lane & 8388096) && - null !== update && - ((fiber = queue.lanes), - (fiber &= update.pendingLanes), - (lane |= fiber), - (queue.lanes = lane), - markRootEntangled(update, lane)); + scheduleUpdateOnFiber(fiber, lane, eventTime); } } var ContextOnlyDispatcher = { @@ -3921,8 +3846,6 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4098,7 +4021,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4174,15 +4097,14 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) + ) + if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); - 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); - } return updateFunctionComponent( current, workInProgress, @@ -4199,39 +4121,30 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 2)) - (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 + if (0 === (workInProgress.mode & 4)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes(workInProgress, renderLanes); + else if (0 !== (renderLanes & 1073741824)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes( + workInProgress, + null !== prevState ? prevState.baseLanes : renderLanes ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } + else + return ( + (current = + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { baseLanes: current }), + pushRenderLanes(workInProgress, current), + null + ); else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + pushRenderLanes(workInProgress, nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4241,7 +4154,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 256; + workInProgress.flags |= 128; } function updateFunctionComponent( current, @@ -4266,7 +4179,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4441,7 +4354,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 512)) + (workInProgress.flags |= 256)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4449,7 +4362,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4463,7 +4376,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (nextProps = !1)); } return finishClassComponent( @@ -4484,7 +4397,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 128); + var didCaptureError = 0 !== (workInProgress.flags & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4528,21 +4441,18 @@ function pushHostRootContext(workInProgress) { 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 = 0 !== (workInProgress.flags & 64)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -129)) + ? ((showFallback = !0), (workInProgress.flags &= -65)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4559,9 +4469,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4573,11 +4481,9 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 8388608), + (workInProgress.lanes = 33554432), current ); renderLanes = createFiberFromOffscreen( @@ -4603,11 +4509,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4634,11 +4537,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4661,7 +4561,7 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && null !== progressedPrimaryFragment + 0 === (mode & 2) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren)) : (progressedPrimaryFragment = createFiberFromOffscreen( @@ -4694,14 +4594,13 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 2) && (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)); + ((current.nextEffect = null), + (current.flags = 8), + (workInProgress.firstEffect = workInProgress.lastEffect = current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4711,22 +4610,26 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child; + current = currentPrimaryChildFragment.sibling; + var primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - (workInProgress.deletions = null)) - : ((primaryChildren = createWorkInProgress(current, primaryChildProps)), - (primaryChildren.subtreeFlags = current.subtreeFlags & 131072)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) + (currentPrimaryChildFragment = primaryChildren.lastEffect), + null !== currentPrimaryChildFragment + ? ((workInProgress.firstEffect = primaryChildren.firstEffect), + (workInProgress.lastEffect = currentPrimaryChildFragment), + (currentPrimaryChildFragment.nextEffect = null)) + : (workInProgress.firstEffect = workInProgress.lastEffect = null)) + : (primaryChildren = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )); + null !== current + ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4751,7 +4654,8 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode + tailMode, + lastEffectBeforeRendering ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4761,14 +4665,16 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode)); + (renderState.tailMode = tailMode), + (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4777,9 +4683,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); else { - if (null !== current && 0 !== (current.flags & 128)) + if (null !== current && 0 !== (current.flags & 64)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4802,7 +4708,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4823,7 +4729,8 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "backwards": @@ -4845,11 +4752,19 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + initSuspenseListRenderState( + workInProgress, + !1, + null, + null, + void 0, + workInProgress.lastEffect + ); break; default: workInProgress.memoizedState = null; @@ -4859,23 +4774,25 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) { null !== current && (workInProgress.dependencies = current.dependencies); 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; + if (0 !== (renderLanes & workInProgress.childLanes)) { + 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; } - return workInProgress.child; + return null; } var appendAllChildren, updateHostContainer, @@ -4922,40 +4839,16 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$62 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$62 = lastTailNode), + for (var lastTailNode$64 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$64 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$62 + null === lastTailNode$64 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$62.sibling = null); + : (lastTailNode$64.sibling = null); } } -function bubbleProperties(completedWork) { - var didBailout = - null !== completedWork.alternate && - completedWork.alternate.child === completedWork.child, - newChildLanes = 0, - subtreeFlags = 0; - if (didBailout) - for (var child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags & 131072), - (subtreeFlags |= child$63.flags & 131072), - (child$63.return = completedWork), - (child$63 = child$63.sibling); - else - for (child$63 = completedWork.child; null !== child$63; ) - (newChildLanes |= child$63.lanes | child$63.childLanes), - (subtreeFlags |= child$63.subtreeFlags), - (subtreeFlags |= child$63.flags), - (child$63.return = completedWork), - (child$63 = child$63.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -4969,80 +4862,76 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return bubbleProperties(workInProgress), null; + return null; case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 3: return ( - (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), + (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), + (workInProgress.flags |= 256), + updateHostContainer(workInProgress), null ); case 5: popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderLanes = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderLanes, newProps, - renderLanes + rootContainerInstance ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + current.ref !== workInProgress.ref && (workInProgress.flags |= 128); 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); + renderLanes = getViewConfigForType(renderLanes); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderLanes.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - type.uiViewClassName, - renderLanes, + renderLanes.uiViewClassName, + rootContainerInstance, updatePayload ); - renderLanes = new ReactNativeFiberHostComponent( + rootContainerInstance = new ReactNativeFiberHostComponent( current, - type, + renderLanes, 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); + appendAllChildren(rootContainerInstance, workInProgress, !1, !1); + workInProgress.stateNode = rootContainerInstance; + finalizeInitialChildren(rootContainerInstance) && + (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 128); } - bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5062,27 +4951,27 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - renderLanes = allocateTag(); + rootContainerInstance = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderLanes, + rootContainerInstance, "RCTRawText", current, { text: newProps } ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; } - bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) + if (0 !== (workInProgress.flags & 64)) return (workInProgress.lanes = renderLanes), workInProgress; newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) + rootContainerInstance = !1; + null !== current && + (rootContainerInstance = null !== current.memoizedState); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5097,92 +4986,82 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || + (0 === (workInProgressRootSkippedLanes & 134217727) && + 0 === (workInProgressRootUpdatedLanes & 134217727)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || renderLanes) workInProgress.flags |= 4; - bubbleProperties(workInProgress); + if (newProps || rootContainerInstance) workInProgress.flags |= 4; return null; case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); + return popProvider(workInProgress), null; case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 19: pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.flags & 64); + updatePayload = newProps.rendering; if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) + (null !== current && 0 !== (current.flags & 64)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); + workInProgress.flags |= 64; + cutOffTailIfNeeded(newProps, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), - (type = current), - (renderLanes.flags &= 131074), - (updatePayload = renderLanes.alternate), + (rootContainerInstance = newProps), + (renderLanes = current), + (rootContainerInstance.flags &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (updatePayload = rootContainerInstance.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 = updatePayload.subtreeFlags), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = + ? ((rootContainerInstance.childLanes = 0), + (rootContainerInstance.lanes = renderLanes), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.stateNode = null)) + : ((rootContainerInstance.childLanes = + updatePayload.childLanes), + (rootContainerInstance.lanes = updatePayload.lanes), + (rootContainerInstance.child = updatePayload.child), + (rootContainerInstance.memoizedProps = updatePayload.memoizedProps), - (renderLanes.memoizedState = + (rootContainerInstance.memoizedState = updatePayload.memoizedState), - (renderLanes.updateQueue = updatePayload.updateQueue), - (renderLanes.type = updatePayload.type), - (type = updatePayload.dependencies), - (renderLanes.dependencies = - null === type + (rootContainerInstance.updateQueue = + updatePayload.updateQueue), + (rootContainerInstance.type = updatePayload.type), + (renderLanes = updatePayload.dependencies), + (rootContainerInstance.dependencies = + null === renderLanes ? null : { - lanes: type.lanes, - firstContext: type.firstContext + lanes: renderLanes.lanes, + firstContext: renderLanes.firstContext })), (newProps = newProps.sibling); push( @@ -5193,74 +5072,78 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== type.tail && + null !== newProps.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608)); + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432)); } else { - if (!newProps) + if (!rootContainerInstance) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 128), - (newProps = !0), + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && !updatePayload.alternate) ) - return bubbleProperties(workInProgress), null; + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - 2 * now() - type.renderingStartTime > + 2 * now() - newProps.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608)); - type.isBackwards + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432)); + newProps.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), + : ((current = newProps.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + (newProps.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; + return null !== newProps.tail + ? ((current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (workInProgress = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 + ), + current) + : null; case 22: case 23: return ( popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== renderLanes && + (null !== current.memoizedState) !== + (null !== workInProgress.memoizedState) && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), - (renderLanes && - 0 === (subtreeRenderLanes & 1073741824) && - 0 !== (workInProgress.mode & 2)) || - bubbleProperties(workInProgress), null ); } @@ -5275,8 +5158,8 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) + return flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) : null; case 3: popHostContainer(); @@ -5284,11 +5167,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 128)) + if (0 !== (flags & 64)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -16385) | 128; + workInProgress.flags = (flags & -8193) | 64; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5296,8 +5179,8 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), workInProgress) + flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), workInProgress) : null ); case 19: @@ -5305,12 +5188,10 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type._context), null; + return popProvider(workInProgress), null; case 22: case 23: return popRenderLanes(), null; - case 24: - return null; default: return null; } @@ -5383,150 +5264,140 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null; -function safelyDetachRef(current, nearestMountedAncestor) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; +function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, nearestMountedAncestor, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -var focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = null; - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) - doesFiberContain(firstChild[i], focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - firstChild = root.child; - if (0 !== (root.subtreeFlags & 516) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var current = root.alternate, - flags = root.flags; - if ( - !shouldFireAfterActiveInstanceBlur && - null !== focusedInstanceHandle - ) { - var JSCompiler_temp; - if ((JSCompiler_temp = 13 === root.tag)) - a: { - if (null !== current) { - var oldState = current.memoizedState; - if (null === oldState || null !== oldState.dehydrated) { - var newState = root.memoizedState; - JSCompiler_temp = - null !== newState && null === newState.dehydrated; - break a; - } - } - JSCompiler_temp = !1; - } - JSCompiler_temp && - doesFiberContain(root, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - } - if (0 !== (flags & 512)) - switch (root.tag) { - case 0: - case 11: - case 15: - break; - case 1: - if (null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState, - instance = root.stateNode, - snapshot = instance.getSnapshotBeforeUpdate( - root.elementType === root.type - ? prevProps - : resolveDefaultProps(root.type, prevProps), - prevState - ); - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - break; - case 3: - break; - case 5: - case 6: - case 4: - case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + return; + case 1: + if (finishedWork.flags & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } + return; + case 3: + return; + case 5: + case 6: + case 4: + case 17: + return; } - current = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - focusedInstanceHandle = null; - return current; + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor$jscomp$0 -) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; - if (void 0 !== destroy) { - var current = finishedWork, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); +function commitLifeCycles(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + if (3 === (finishedRoot.tag & 3)) { + var create$81 = finishedRoot.create; + finishedRoot.destroy = create$81(); } - } + finishedRoot = finishedRoot.next; + } while (finishedRoot !== current); } - effect = effect.next; - } while (effect !== updateQueue); - } -} -function commitHookEffectListMount(tag, finishedWork) { - finishedWork = finishedWork.updateQueue; - finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; - if (null !== finishedWork) { - var effect = (finishedWork = finishedWork.next); - do { - if ((effect.tag & tag) === tag) { - var create$80 = effect.create; - effect.destroy = create$80(); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + var _effect = finishedRoot; + create$81 = _effect.next; + _effect = _effect.tag; + 0 !== (_effect & 4) && + 0 !== (_effect & 1) && + (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), + enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); + finishedRoot = create$81; + } while (finishedRoot !== current); + } + return; + case 1: + finishedRoot = finishedWork.stateNode; + finishedWork.flags & 4 && + (null === current + ? finishedRoot.componentDidMount() + : ((create$81 = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current.memoizedProps + )), + finishedRoot.componentDidUpdate( + create$81, + current.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ))); + current = finishedWork.updateQueue; + null !== current && + commitUpdateQueue(finishedWork, current, finishedRoot); + return; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue(finishedWork, current, finishedRoot); } - effect = effect.next; - } while (effect !== finishedWork); + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + case 22: + case 23: + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5586,7 +5457,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { +function commitUnmount(finishedRoot, current) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5603,24 +5474,26 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect = effect, - destroy = _effect.destroy; - _effect = _effect.tag; - if (void 0 !== destroy && 0 !== (_effect & 2)) { - _effect = current; - var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect, nearestMountedAncestor, error); + var _effect2 = effect, + destroy = _effect2.destroy; + _effect2 = _effect2.tag; + if (void 0 !== destroy) + if (0 !== (_effect2 & 4)) + enqueuePendingPassiveHookEffectUnmount(current, effect); + else { + _effect2 = current; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect2, error); + } } - } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current, nearestMountedAncestor$jscomp$0); + safelyDetachRef(current); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5628,34 +5501,26 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError( - current, - nearestMountedAncestor$jscomp$0, - unmountError - ); + captureCommitPhaseError(current, unmountError); } break; case 5: - safelyDetachRef(current, nearestMountedAncestor$jscomp$0); + safelyDetachRef(current); break; case 4: - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor$jscomp$0 - ); + unmountHostComponents(finishedRoot, current); } } -function detachFiberAfterEffects(fiber) { +function detachFiberMutation(fiber) { fiber.alternate = null; fiber.child = null; - fiber.deletions = null; fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; + fiber.return = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5690,7 +5555,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 32 && (parentFiber.flags &= -33); + parentFiber.flags & 16 && (parentFiber.flags &= -17); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5806,11 +5671,7 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents( - finishedRoot$jscomp$0, - current, - nearestMountedAncestor$jscomp$0 -) { +function unmountHostComponents(finishedRoot$jscomp$0, current) { for ( var node = current, currentParentIsValid = !1, @@ -5848,13 +5709,12 @@ function unmountHostComponents( a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), + (commitUnmount(finishedRoot, node$jscomp$0), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5881,18 +5741,18 @@ function unmountHostComponents( [0] )) : ((finishedRoot = currentParent), - (nearestMountedAncestor = node.stateNode), - recursivelyUncacheFiberNode(nearestMountedAncestor), + (node$jscomp$0 = node.stateNode), + recursivelyUncacheFiberNode(node$jscomp$0), (root = finishedRoot._children), - (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), - root.splice(nearestMountedAncestor, 1), + (node$jscomp$0 = root.indexOf(node$jscomp$0)), + root.splice(node$jscomp$0, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [nearestMountedAncestor] + [node$jscomp$0] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -5903,12 +5763,7 @@ function unmountHostComponents( continue; } } else if ( - (commitUnmount( - finishedRoot$jscomp$0, - node, - nearestMountedAncestor$jscomp$0 - ), - null !== node.child) + (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) ) { node.child.return = node; node = node.child; @@ -5930,31 +5785,42 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do + 3 === (effect.tag & 3) && + ((finishedWork = effect.destroy), + (effect.destroy = void 0), + void 0 !== finishedWork && finishedWork()), + (effect = effect.next); + while (effect !== updateQueue); + } return; case 1: return; case 5: - var instance = finishedWork.stateNode; - if (null != instance) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + updateQueue = finishedWork.stateNode; + if (null != updateQueue) { + effect = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : effect; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = instance.viewConfig), - instanceProps.set(instance._nativeTag, newProps), - (newProps = diffProperties( + ((finishedWork = updateQueue.viewConfig), + instanceProps.set(updateQueue._nativeTag, effect), + (effect = diffProperties( null, current, - newProps, + effect, finishedWork.validAttributes )), - null != newProps && + null != effect && ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, + updateQueue._nativeTag, finishedWork.uiViewClassName, - newProps + effect )); } return; @@ -5982,217 +5848,42 @@ function commitWork(current, finishedWork) { case 19: attachSuspenseRetryListeners(finishedWork); return; - case 17: - return; - case 22: - case 23: - hideOrUnhideAllChildren( - finishedWork, - null !== finishedWork.memoizedState - ); - return; - } - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); -} -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (retryCache.add(wakeable), wakeable.then(retry, retry)); - }); - } -} -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - renderPriorityLevel = nextEffect; - firstChild = renderPriorityLevel.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) { - var childToDelete = firstChild[i]; - try { - unmountHostComponents(root, childToDelete, renderPriorityLevel); - var alternate = childToDelete.alternate; - childToDelete.return = null; - null !== alternate && (alternate.return = null); - } catch (error) { - captureCommitPhaseError(childToDelete, renderPriorityLevel, error); - } - } - firstChild = renderPriorityLevel.child; - if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) - (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - renderPriorityLevel = nextEffect; - try { - var flags = renderPriorityLevel.flags; - if (flags & 256) { - var current = renderPriorityLevel.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 2054) { - case 2: - commitPlacement(renderPriorityLevel); - renderPriorityLevel.flags &= -3; - break; - case 6: - commitPlacement(renderPriorityLevel); - renderPriorityLevel.flags &= -3; - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - break; - case 2048: - renderPriorityLevel.flags &= -2049; - break; - case 2052: - renderPriorityLevel.flags &= -2049; - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - break; - case 4: - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - } - } catch (error) { - captureCommitPhaseError( - renderPriorityLevel, - renderPriorityLevel.return, - error - ); - } - firstChild = renderPriorityLevel.sibling; - if (null !== firstChild) { - firstChild.return = renderPriorityLevel.return; - nextEffect = firstChild; - break; - } - nextEffect = renderPriorityLevel.return; - } + case 17: + return; + case 22: + case 23: + hideOrUnhideAllChildren( + finishedWork, + null !== finishedWork.memoizedState + ); + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function commitLayoutEffects(finishedWork) { - for (nextEffect = finishedWork; null !== nextEffect; ) { - var fiber = nextEffect, - firstChild = fiber.child; - if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) - (firstChild.return = fiber), (nextEffect = firstChild); - else - for (fiber = finishedWork; null !== nextEffect; ) { - firstChild = nextEffect; - if (0 !== (firstChild.flags & 324)) { - var current = firstChild.alternate; - try { - if (0 !== (firstChild.flags & 68)) - switch (firstChild.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(3, firstChild); - break; - case 1: - var instance = firstChild.stateNode; - if (firstChild.flags & 4) - if (null === current) instance.componentDidMount(); - else { - var prevProps = - firstChild.elementType === firstChild.type - ? current.memoizedProps - : resolveDefaultProps( - firstChild.type, - current.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = firstChild.updateQueue; - null !== updateQueue && - commitUpdateQueue(firstChild, updateQueue, instance); - break; - case 3: - var updateQueue$81 = firstChild.updateQueue; - if (null !== updateQueue$81) { - current = null; - if (null !== firstChild.child) - switch (firstChild.child.tag) { - case 5: - current = firstChild.child.stateNode; - break; - case 1: - current = firstChild.child.stateNode; - } - commitUpdateQueue(firstChild, updateQueue$81, current); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - break; - case 13: - break; - case 19: - case 17: - case 21: - case 22: - case 23: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - if (firstChild.flags & 256) { - current = void 0; - var ref = firstChild.ref; - if (null !== ref) { - var instance$jscomp$0 = firstChild.stateNode; - switch (firstChild.tag) { - case 5: - current = instance$jscomp$0; - break; - default: - current = instance$jscomp$0; - } - "function" === typeof ref - ? ref(current) - : (ref.current = current); - } - } - } catch (error) { - captureCommitPhaseError(firstChild, firstChild.return, error); - } - } - if (firstChild === fiber) { - nextEffect = null; - break; - } - current = firstChild.sibling; - if (null !== current) { - current.return = firstChild.return; - nextEffect = current; - break; - } - nextEffect = firstChild.return; - } +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (retryCache.add(wakeable), wakeable.then(retry, retry)); + }); } } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + return null !== current && + ((current = current.memoizedState), + null === current || null !== current.dehydrated) + ? ((finishedWork = finishedWork.memoizedState), + null !== finishedWork && null === finishedWork.dehydrated) + : !1; +} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -6204,22 +5895,30 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, + workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, + mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, rootDoesHavePassiveEffects = !1, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, + pendingPassiveHookEffectsMount = [], + pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, currentEventTime = -1, - currentEventTransitionLane = 0; + currentEventWipLanes = 0, + currentEventPendingLanes = 0, + focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6229,22 +5928,30 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 1)) return 1; - if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - if (0 !== ReactCurrentBatchConfig.transition) - return ( - 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), - (currentEventTransitionLane = fiber)), - currentEventTransitionLane - ); + if (0 === (fiber & 2)) return 1; + if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + 0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes); + if (0 !== ReactCurrentBatchConfig.transition) { + 0 !== currentEventPendingLanes && + (currentEventPendingLanes = + null !== mostRecentlyUpdatedRoot + ? mostRecentlyUpdatedRoot.pendingLanes + : 0); + fiber = currentEventWipLanes; + var lane = 4186112 & ~currentEventPendingLanes; + lane &= -lane; + 0 === lane && + ((fiber = 4186112 & ~fiber), + (lane = fiber & -fiber), + 0 === lane && (lane = 8192)); + return lane; + } fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12)) + ? (fiber = findUpdateLane(12, currentEventWipLanes)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber))); + (fiber = findUpdateLane(fiber, currentEventWipLanes))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6275,7 +5982,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { ? (rootsWithPendingDiscreteUpdates = new Set([fiber])) : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime)); - return fiber; + mostRecentlyUpdatedRoot = fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6300,15 +6007,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$6 = 31 - clz32(lanes), - lane = 1 << index$6, - expirationTime = expirationTimes[index$6]; + var index$7 = 31 - clz32(lanes), + lane = 1 << index$7, + expirationTime = expirationTimes[index$7]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$6] = + expirationTimes[index$7] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6323,42 +6030,45 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - 0 === suspendedLanes - ? (null !== existingCallbackNode && + if (0 === suspendedLanes) + null !== existingCallbackNode && + (existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)) - : root.callbackPriority !== currentTime && - (null != existingCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = null)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority( - currentTime - )), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))), - (root.callbackPriority = currentTime), - (root.callbackNode = existingCallbackNode)); -} -function performConcurrentWorkOnRoot(root, didTimeout) { + (root.callbackPriority = 0)); + else { + if (null !== existingCallbackNode) { + if (root.callbackPriority === currentTime) return; + existingCallbackNode !== fakeCallbackNode && + Scheduler_cancelCallback(existingCallbackNode); + } + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = fakeCallbackNode)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))); + root.callbackPriority = currentTime; + root.callbackNode = existingCallbackNode; + } +} +function performConcurrentWorkOnRoot(root) { currentEventTime = -1; - currentEventTransitionLane = 0; + currentEventPendingLanes = currentEventWipLanes = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6369,22 +6079,16 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - (root.expiredLanes |= lanes & root.pendingLanes), - ensureRootIsScheduled(root, now()), - null - ); - didTimeout = lanes; + var exitStatus = lanes; var prevExecutionContext = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( workInProgressRoot !== root || - workInProgressRootRenderLanes !== didTimeout + workInProgressRootRenderLanes !== exitStatus ) (workInProgressRootRenderTargetTime = now() + 500), - prepareFreshStack(root, didTimeout); + prepareFreshStack(root, exitStatus); do try { workLoopConcurrent(); @@ -6397,17 +6101,19 @@ function performConcurrentWorkOnRoot(root, didTimeout) { ReactCurrentDispatcher$2.current = prevDispatcher; executionContext = prevExecutionContext; null !== workInProgress - ? (didTimeout = 0) + ? (exitStatus = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); - if (0 !== didTimeout) { - 2 === didTimeout && + (exitStatus = workInProgressRootExitStatus)); + if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) + prepareFreshStack(root, 0); + else if (0 !== exitStatus) { + 2 === exitStatus && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); - if (1 === didTimeout) + 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (1 === exitStatus) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6415,7 +6121,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (didTimeout) { + switch (exitStatus) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6425,9 +6131,9 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 125829120) === lanes && - ((didTimeout = globalMostRecentFallbackTime + 500 - now()), - 10 < didTimeout) + (lanes & 62914560) === lanes && + ((exitStatus = globalMostRecentFallbackTime + 500 - now()), + 10 < exitStatus) ) { if (0 !== getNextLanes(root, 0)) break; prevExecutionContext = root.suspendedLanes; @@ -6438,7 +6144,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - didTimeout + exitStatus ); break; } @@ -6446,13 +6152,13 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 8388096) === lanes) break; - didTimeout = root.eventTimes; + if ((lanes & 4186112) === lanes) break; + exitStatus = root.eventTimes; for (prevExecutionContext = -1; 0 < lanes; ) { - var index$5 = 31 - clz32(lanes); - prevDispatcher = 1 << index$5; - index$5 = didTimeout[index$5]; - index$5 > prevExecutionContext && (prevExecutionContext = index$5); + var index$6 = 31 - clz32(lanes); + prevDispatcher = 1 << index$6; + index$6 = exitStatus[index$6]; + index$6 > prevExecutionContext && (prevExecutionContext = index$6); lanes &= ~prevDispatcher; } lanes = prevExecutionContext; @@ -6498,9 +6204,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$7 = 31 - clz32(suspendedLanes), - lane = 1 << index$7; - root[index$7] = -1; + var index$11 = 31 - clz32(suspendedLanes), + lane = 1 << index$11; + root[index$11] = -1; suspendedLanes &= ~lane; } } @@ -6508,12 +6214,17 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes = + if ( root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ? workInProgressRootRenderLanes - : getNextLanes(root, 0); - var exitStatus = renderRootSync(root, lanes); + ) { + var lanes = workInProgressRootRenderLanes; + var exitStatus = renderRootSync(root, lanes); + 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && + ((lanes = getNextLanes(root, lanes)), + (exitStatus = renderRootSync(root, lanes))); + } else + (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6532,6 +6243,11 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } +function pushRenderLanes(fiber, lanes) { + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= lanes; + workInProgressRootIncludedLanes |= lanes; +} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6571,7 +6287,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type._context); + popProvider(interruptedWork); break; case 22: case 23: @@ -6581,29 +6297,10 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - if (null !== interleavedQueues) { - for (root = 0; root < interleavedQueues.length; root++) - if ( - ((lanes = interleavedQueues[root]), - (timeoutHandle = lanes.interleaved), - null !== timeoutHandle) - ) { - lanes.interleaved = null; - interruptedWork = timeoutHandle.next; - var lastPendingUpdate = lanes.pending; - if (null !== lastPendingUpdate) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = interruptedWork; - timeoutHandle.next = firstPendingUpdate; - } - lanes.pending = timeoutHandle; - } - interleavedQueues = null; - } } function handleError(root$jscomp$0, thrownValue) { do { @@ -6639,18 +6336,15 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 8192; + sourceFiber.flags |= 4096; + sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value, - tag = sourceFiber.tag; - if ( - 0 === (sourceFiber.mode & 1) && - (0 === tag || 11 === tag || 15 === tag) - ) { + var wakeable = value; + if (0 === (sourceFiber.mode & 2)) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6661,15 +6355,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$75 = returnFiber; + workInProgress$76 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$75.tag)) { - var nextState = workInProgress$75.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$76.tag)) { + var nextState = workInProgress$76.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$75.memoizedProps; + var props = workInProgress$76.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6681,19 +6375,16 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$75.updateQueue; + var wakeables = workInProgress$76.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$75.updateQueue = updateQueue; + workInProgress$76.updateQueue = updateQueue; } else wakeables.add(wakeable); - if ( - 0 === (workInProgress$75.mode & 1) && - workInProgress$75 !== returnFiber - ) { - workInProgress$75.flags |= 128; - sourceFiber.flags |= 65536; - sourceFiber.flags &= -10053; + if (0 === (workInProgress$76.mode & 2)) { + workInProgress$76.flags |= 64; + sourceFiber.flags |= 32768; + sourceFiber.flags &= -5029; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6724,12 +6415,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$75.flags |= 16384; - workInProgress$75.lanes = thrownValue; + workInProgress$76.flags |= 8192; + workInProgress$76.lanes = thrownValue; break a; } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$76 = workInProgress$76.return; + } while (null !== workInProgress$76); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6738,47 +6429,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$75 = returnFiber; + workInProgress$76 = returnFiber; do { - switch (workInProgress$75.tag) { + switch (workInProgress$76.tag) { case 3: root = value; - workInProgress$75.flags |= 16384; + workInProgress$76.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$76 = createRootErrorUpdate( - workInProgress$75, + workInProgress$76.lanes |= thrownValue; + var update$77 = createRootErrorUpdate( + workInProgress$76, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$76); + enqueueCapturedUpdate(workInProgress$76, update$77); break a; case 1: root = value; - var ctor = workInProgress$75.type, - instance = workInProgress$75.stateNode; + var ctor = workInProgress$76.type, + instance = workInProgress$76.stateNode; if ( - 0 === (workInProgress$75.flags & 128) && + 0 === (workInProgress$76.flags & 64) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$75.flags |= 16384; + workInProgress$76.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$75.lanes |= thrownValue; - var update$79 = createClassErrorUpdate( - workInProgress$75, + workInProgress$76.lanes |= thrownValue; + var update$80 = createClassErrorUpdate( + workInProgress$76, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$75, update$79); + enqueueCapturedUpdate(workInProgress$76, update$80); break a; } } - workInProgress$75 = workInProgress$75.return; - } while (null !== workInProgress$75); + workInProgress$76 = workInProgress$76.return; + } while (null !== workInProgress$76); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6839,25 +6530,47 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 8192)) { - if ( - ((current = completeWork(current, completedWork, subtreeRenderLanes)), - null !== current) - ) { + if (0 === (completedWork.flags & 4096)) { + current = completeWork(current, completedWork, subtreeRenderLanes); + if (null !== current) { workInProgress = current; return; } + current = completedWork; + if ( + (23 !== current.tag && 22 !== current.tag) || + null === current.memoizedState || + 0 !== (subtreeRenderLanes & 1073741824) || + 0 === (current.mode & 4) + ) { + for (var newChildLanes = 0, child = current.child; null !== child; ) + (newChildLanes |= child.lanes | child.childLanes), + (child = child.sibling); + current.childLanes = newChildLanes; + } + null !== unitOfWork && + 0 === (unitOfWork.flags & 4096) && + (null === unitOfWork.firstEffect && + (unitOfWork.firstEffect = completedWork.firstEffect), + null !== completedWork.lastEffect && + (null !== unitOfWork.lastEffect && + (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), + (unitOfWork.lastEffect = completedWork.lastEffect)), + 1 < completedWork.flags && + (null !== unitOfWork.lastEffect + ? (unitOfWork.lastEffect.nextEffect = completedWork) + : (unitOfWork.firstEffect = completedWork), + (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 8191; + current.flags &= 4095; workInProgress = current; return; } null !== unitOfWork && - ((unitOfWork.flags |= 8192), - (unitOfWork.subtreeFlags = 0), - (unitOfWork.deletions = null)); + ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), + (unitOfWork.flags |= 4096)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -6878,8 +6591,7 @@ function commitRootImpl(root, renderPriorityLevel) { while (null !== rootWithPendingPassiveEffects); if (0 !== (executionContext & 48)) throw Error("Should not already be working."); - var finishedWork = root.finishedWork, - lanes = root.finishedLanes; + var finishedWork = root.finishedWork; if (null === finishedWork) return null; root.finishedWork = null; root.finishedLanes = 0; @@ -6888,48 +6600,174 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - markRootFinished(root, remainingLanes); + var remainingLanes = finishedWork.lanes | finishedWork.childLanes, + remainingLanes$jscomp$0 = remainingLanes, + noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; + root.pendingLanes = remainingLanes$jscomp$0; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes$jscomp$0; + root.mutableReadLanes &= remainingLanes$jscomp$0; + root.entangledLanes &= remainingLanes$jscomp$0; + remainingLanes$jscomp$0 = root.entanglements; + for ( + var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; + 0 < noLongerPendingLanes; + + ) { + var index$12 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$12; + remainingLanes$jscomp$0[index$12] = 0; + eventTimes[index$12] = -1; + expirationTimes[index$12] = -1; + noLongerPendingLanes &= ~lane; + } null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 8) && + 0 === (remainingLanes & 24) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 1040) && - 0 === (finishedWork.flags & 1040)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - remainingLanes = 0 !== (finishedWork.flags & 8054); - 0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes - ? ((remainingLanes = executionContext), - (executionContext |= 32), - (ReactCurrentOwner$2.current = null), - commitBeforeMutationEffects(root, finishedWork), - commitMutationEffects(root, renderPriorityLevel, finishedWork), - (root.current = finishedWork), - commitLayoutEffects(finishedWork, root, lanes), - requestPaint(), - (executionContext = remainingLanes)) - : (root.current = finishedWork); - rootDoesHavePassiveEffects && - ((rootDoesHavePassiveEffects = !1), - (rootWithPendingPassiveEffects = root), - (pendingPassiveEffectsRenderPriority = renderPriorityLevel)); + 1 < finishedWork.flags + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (remainingLanes = finishedWork.firstEffect)) + : (remainingLanes = finishedWork) + : (remainingLanes = finishedWork.firstEffect); + if (null !== remainingLanes) { + remainingLanes$jscomp$0 = executionContext; + executionContext |= 32; + focusedInstanceHandle = ReactCurrentOwner$2.current = null; + shouldFireAfterActiveInstanceBlur = !1; + nextEffect = remainingLanes; + do + try { + commitBeforeMutationEffects(); + } catch (error) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + focusedInstanceHandle = null; + nextEffect = remainingLanes; + do + try { + for (eventTimes = root; null !== nextEffect; ) { + var flags = nextEffect.flags; + if (flags & 128) { + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 1038) { + case 2: + commitPlacement(nextEffect); + nextEffect.flags &= -3; + break; + case 6: + commitPlacement(nextEffect); + nextEffect.flags &= -3; + commitWork(nextEffect.alternate, nextEffect); + break; + case 1024: + nextEffect.flags &= -1025; + break; + case 1028: + nextEffect.flags &= -1025; + commitWork(nextEffect.alternate, nextEffect); + break; + case 4: + commitWork(nextEffect.alternate, nextEffect); + break; + case 8: + expirationTimes = nextEffect; + unmountHostComponents(eventTimes, expirationTimes); + var alternate = expirationTimes.alternate; + detachFiberMutation(expirationTimes); + null !== alternate && detachFiberMutation(alternate); + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$88) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$88); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + root.current = finishedWork; + nextEffect = remainingLanes; + do + try { + for (flags = root; null !== nextEffect; ) { + var flags$jscomp$0 = nextEffect.flags; + flags$jscomp$0 & 36 && + commitLifeCycles(flags, nextEffect.alternate, nextEffect); + if (flags$jscomp$0 & 128) { + current = void 0; + var ref = nextEffect.ref; + if (null !== ref) { + var instance = nextEffect.stateNode; + switch (nextEffect.tag) { + case 5: + current = instance; + break; + default: + current = instance; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$89) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$89); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + nextEffect = null; + requestPaint(); + executionContext = remainingLanes$jscomp$0; + } else root.current = finishedWork; + if (rootDoesHavePassiveEffects) + (rootDoesHavePassiveEffects = !1), + (rootWithPendingPassiveEffects = root), + (pendingPassiveEffectsRenderPriority = renderPriorityLevel); + else + for (nextEffect = remainingLanes; null !== nextEffect; ) + (renderPriorityLevel = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + nextEffect.flags & 8 && + ((flags$jscomp$0 = nextEffect), + (flags$jscomp$0.sibling = null), + (flags$jscomp$0.stateNode = null)), + (nextEffect = renderPriorityLevel); remainingLanes = root.pendingLanes; 0 === remainingLanes && (legacyErrorBoundariesThatAlreadyFailed = null); - 0 !== (remainingLanes & 1) + 1 === remainingLanes ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + finishedWork = finishedWork.stateNode; + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + finishedWork, + void 0, + 64 === (finishedWork.current.flags & 64) + ); + } catch (err) {} ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -6940,6 +6778,30 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } +function commitBeforeMutationEffects() { + for (; null !== nextEffect; ) { + var current = nextEffect.alternate; + shouldFireAfterActiveInstanceBlur || + null === focusedInstanceHandle || + (0 !== (nextEffect.flags & 8) + ? doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0) + : 13 === nextEffect.tag && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0)); + var flags = nextEffect.flags; + 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); + 0 === (flags & 512) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + nextEffect = nextEffect.nextEffect; + } +} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -6951,6 +6813,24 @@ function flushPassiveEffects() { } return !1; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects; @@ -6959,103 +6839,40 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - for (nextEffect = root.current; null !== nextEffect; ) { - var fiber = nextEffect, - child = fiber.child; - if (0 !== (nextEffect.flags & 16)) { - var deletions = fiber.deletions; - if (null !== deletions) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - for (nextEffect = fiberToDelete; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); - } - var child$jscomp$0 = fiber$jscomp$0.child; - if (null !== child$jscomp$0) - (child$jscomp$0.return = fiber$jscomp$0), - (nextEffect = child$jscomp$0); - else - for (; null !== nextEffect; ) { - fiber$jscomp$0 = nextEffect; - if (fiber$jscomp$0 === fiberToDelete) { - nextEffect = null; - break; - } - child$jscomp$0 = fiber$jscomp$0.sibling; - if (null !== child$jscomp$0) { - child$jscomp$0.return = fiber$jscomp$0.return; - nextEffect = child$jscomp$0; - break; - } - nextEffect = fiber$jscomp$0.return; - } - } - fiber$jscomp$0 = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); - null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); - } - nextEffect = fiber; + var unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + for (var i = 0; i < unmountEffects.length; i += 2) { + var effect$94 = unmountEffects[i], + fiber = unmountEffects[i + 1], + destroy = effect$94.destroy; + effect$94.destroy = void 0; + if ("function" === typeof destroy) + try { + destroy(); + } catch (error) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error); } + } + unmountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + for (i = 0; i < unmountEffects.length; i += 2) { + effect$94 = unmountEffects[i]; + fiber = unmountEffects[i + 1]; + try { + var create$98 = effect$94.create; + effect$94.destroy = create$98(); + } catch (error$99) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error$99); } - if (0 !== (fiber.subtreeFlags & 1040) && null !== child) - (child.return = fiber), (nextEffect = child); - else - a: for (; null !== nextEffect; ) { - fiber = nextEffect; - if (0 !== (fiber.flags & 1024)) - switch (fiber.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(5, fiber, fiber.return); - } - child = fiber.sibling; - if (null !== child) { - child.return = fiber.return; - nextEffect = child; - break a; - } - nextEffect = fiber.return; - } } - for (nextEffect = root = root.current; null !== nextEffect; ) - if ( - ((fiber = nextEffect), - (child = fiber.child), - 0 !== (fiber.subtreeFlags & 1040) && null !== child) - ) - (child.return = fiber), (nextEffect = child); - else - a: for (fiber = root; null !== nextEffect; ) { - child = nextEffect; - if (0 !== (child.flags & 1024)) - try { - switch (child.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(5, child); - } - } catch (error) { - captureCommitPhaseError(child, child.return, error); - } - if (child === fiber) { - nextEffect = null; - break a; - } - deletions = child.sibling; - if (null !== deletions) { - deletions.return = child.return; - nextEffect = deletions; - break a; - } - nextEffect = child.return; - } + for (create$98 = root.current.firstEffect; null !== create$98; ) + (root = create$98.nextEffect), + (create$98.nextEffect = null), + create$98.flags & 8 && + ((create$98.sibling = null), (create$98.stateNode = null)), + (create$98 = root); executionContext = prevExecutionContext; flushSyncCallbackQueue(); return !0; @@ -7070,50 +6887,42 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { (markRootUpdated(rootFiber, 1, sourceFiber), ensureRootIsScheduled(rootFiber, sourceFiber)); } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { +function captureCommitPhaseError(sourceFiber, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for ( - nearestMountedAncestor = sourceFiber.return; - null !== nearestMountedAncestor; - - ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error - ); + for (var fiber = sourceFiber.return; null !== fiber; ) { + if (3 === fiber.tag) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); break; - } else if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; + } else if (1 === fiber.tag) { + var instance = fiber.stateNode; if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || + "function" === typeof fiber.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - sourceFiber = createClassErrorUpdate( - nearestMountedAncestor, - sourceFiber, - 1 - ); - enqueueUpdate(nearestMountedAncestor, sourceFiber); - sourceFiber = requestEventTime(); - nearestMountedAncestor = markUpdateLaneFromFiberToRoot( - nearestMountedAncestor, - 1 - ); - null !== nearestMountedAncestor && - (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber)); + var update = createClassErrorUpdate(fiber, sourceFiber, 1); + enqueueUpdate(fiber, update); + update = requestEventTime(); + fiber = markUpdateLaneFromFiberToRoot(fiber, 1); + if (null !== fiber) + markRootUpdated(fiber, 1, update), + ensureRootIsScheduled(fiber, update); + else if ( + "function" === typeof instance.componentDidCatch && + (null === legacyErrorBoundariesThatAlreadyFailed || + !legacyErrorBoundariesThatAlreadyFailed.has(instance)) + ) + try { + instance.componentDidCatch(error, sourceFiber); + } catch (errorToIgnore) {} break; } } - nearestMountedAncestor = nearestMountedAncestor.return; + fiber = fiber.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7125,7 +6934,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 125829120) === + (workInProgressRootRenderLanes & 62914560) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -7138,13 +6947,14 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 1) + 0 === (wakeable & 2) ? (wakeable = 1) - : 0 === (wakeable & 2) + : 0 === (wakeable & 4) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : ((wakeable = nextRetryLane), - (nextRetryLane <<= 1), - 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); + : (0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes), + (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), + 0 === wakeable && (wakeable = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -7160,83 +6970,78 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; + else if (0 !== (renderLanes & updateLanes)) + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; 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( + 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.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateLanes; + break; + case 13: + if (null !== workInProgress.memoizedState) { + if (0 !== (renderLanes & workInProgress.child.childLanes)) + return updateSuspenseComponent( 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) + workInProgress = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); - } - return 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 & 64)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 64; + } + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); } - didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7248,22 +7053,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateLanes, 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; @@ -7273,8 +7078,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7285,9 +7090,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7299,28 +7104,28 @@ beginWork$1 = function(current, workInProgress, 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; + context = 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); + hasContext = context._init; + context = hasContext(context._payload); + workInProgress.type = context; + hasContext = workInProgress.tag = resolveLazyComponentTag(context); + current = resolveDefaultProps(context, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7329,7 +7134,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7338,7 +7143,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7347,8 +7152,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), + context, + resolveDefaultProps(context.type, current), updateLanes, renderLanes ); @@ -7356,7 +7161,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + context + ". Lazy element type must resolve to a class or function." ); } @@ -7364,32 +7169,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateFunctionComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateClassComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7400,18 +7205,19 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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; + updateLanes = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + updateLanes = workInProgress.memoizedState.element; + updateLanes === context ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7451,16 +7257,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateForwardRef( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7497,21 +7303,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = nextValue.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = hasContext; - if (null !== getDerivedStateFromProps) { - var oldValue = getDerivedStateFromProps.value; - hasContext = objectIs(oldValue, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits(oldValue, hasContext) - : 1073741823) | 0; - if (0 === hasContext) { + hasContext = context.value; + var context$jscomp$0 = workInProgress.type._context; + push(valueCursor, context$jscomp$0._currentValue); + context$jscomp$0._currentValue = hasContext; + if (null !== getDerivedStateFromProps) + if ( + ((context$jscomp$0 = getDerivedStateFromProps.value), + (hasContext = objectIs(context$jscomp$0, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits( + context$jscomp$0, + hasContext + ) + : 1073741823) | 0), + 0 === hasContext) + ) { if ( - getDerivedStateFromProps.children === nextValue.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7523,14 +7335,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7540,24 +7353,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - if (1 === oldValue.tag) { - dependency = createUpdate(-1, renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = oldValue.updateQueue; - if (null !== updateQueue) { - updateQueue = updateQueue.shared; - var pending = updateQueue.pending; - null === pending - ? (dependency.next = dependency) - : ((dependency.next = pending.next), - (pending.next = dependency)); - updateQueue.pending = dependency; - } - } - oldValue.lanes |= renderLanes; - dependency = oldValue.alternate; + 1 === context$jscomp$0.tag && + ((dependency = createUpdate( + -1, + renderLanes & -renderLanes + )), + (dependency.tag = 2), + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.lanes |= renderLanes; + dependency = context$jscomp$0.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath(oldValue.return, renderLanes); + scheduleWorkOnParentPath( + context$jscomp$0.return, + renderLanes + ); list.lanes |= renderLanes; break; } @@ -7565,16 +7374,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7582,21 +7391,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7604,28 +7412,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(context)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - nextValue, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( current, workInProgress, - nextValue, + context, hasContext, updateLanes, renderLanes @@ -7643,11 +7451,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7657,8 +7465,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, updateLanes, context), + mountClassInstance(workInProgress, updateLanes, context, renderLanes), finishClassComponent( null, workInProgress, @@ -7690,8 +7498,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.subtreeFlags = this.flags = 0; - this.deletions = null; + this.flags = 0; + this.lastEffect = this.firstEffect = this.nextEffect = null; this.childLanes = this.lanes = 0; this.alternate = null; } @@ -7729,9 +7537,9 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null)); - workInProgress.flags = current.flags & 131072; + (workInProgress.nextEffect = null), + (workInProgress.firstEffect = null), + (workInProgress.lastEffect = null)); workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -7766,18 +7574,15 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 8; + mode |= 16; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 16); + mode |= 1; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -7964,8 +7769,7 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - element = scheduleUpdateOnFiber(current, lane, eventTime); - null !== element && entangleTransitions(element, current, lane); + scheduleUpdateOnFiber(current, lane, eventTime); return lane; } function emptyFindFiberByHostInstance() { @@ -8004,10 +7808,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_959 = { + devToolsConfig$jscomp$inline_908 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.2", + version: "17.0.1-454c2211c", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8022,11 +7826,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1242 = { - bundleType: devToolsConfig$jscomp$inline_959.bundleType, - version: devToolsConfig$jscomp$inline_959.version, - rendererPackageName: devToolsConfig$jscomp$inline_959.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_959.rendererConfig, +var internals$jscomp$inline_1115 = { + bundleType: devToolsConfig$jscomp$inline_908.bundleType, + version: devToolsConfig$jscomp$inline_908.version, + rendererPackageName: devToolsConfig$jscomp$inline_908.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_908.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8041,7 +7845,7 @@ var internals$jscomp$inline_1242 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_959.findFiberByHostInstance || + devToolsConfig$jscomp$inline_908.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -8050,16 +7854,16 @@ var internals$jscomp$inline_1242 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1243 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1116 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1243.isDisabled && - hook$jscomp$inline_1243.supportsFiber + !hook$jscomp$inline_1116.isDisabled && + hook$jscomp$inline_1116.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1243.inject( - internals$jscomp$inline_1242 + (rendererID = hook$jscomp$inline_1116.inject( + internals$jscomp$inline_1115 )), - (injectedHook = hook$jscomp$inline_1243); + (injectedHook = hook$jscomp$inline_1116); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8108,11 +7912,10 @@ exports.render = function(element, containerTag, callback) { var root = roots.get(containerTag); if (!root) { root = new FiberRootNode(containerTag, 0, !1); - var JSCompiler_inline_result = createFiber(3, null, null, 0); - root.current = JSCompiler_inline_result; - JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; - initializeUpdateQueue(JSCompiler_inline_result); + var uninitializedFiber = createFiber(3, null, null, 0); + root.current = uninitializedFiber; + uninitializedFiber.stateNode = root; + initializeUpdateQueue(uninitializedFiber); roots.set(containerTag, root); } updateContainer(element, root, null, callback); diff --git a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index 680b703d37e6b2..7937b1e922259d 100644 --- a/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -920,7 +920,7 @@ eventPluginOrder = Array.prototype.slice.call([ "ReactNativeBridgeEventPlugin" ]); recomputePluginOrdering(); -var injectedNamesToPlugins$jscomp$inline_219 = { +var injectedNamesToPlugins$jscomp$inline_226 = { ResponderEventPlugin: ResponderEventPlugin, ReactNativeBridgeEventPlugin: { eventTypes: {}, @@ -955,34 +955,34 @@ var injectedNamesToPlugins$jscomp$inline_219 = { } } }, - isOrderingDirty$jscomp$inline_220 = !1, - pluginName$jscomp$inline_221; -for (pluginName$jscomp$inline_221 in injectedNamesToPlugins$jscomp$inline_219) + isOrderingDirty$jscomp$inline_227 = !1, + pluginName$jscomp$inline_228; +for (pluginName$jscomp$inline_228 in injectedNamesToPlugins$jscomp$inline_226) if ( - injectedNamesToPlugins$jscomp$inline_219.hasOwnProperty( - pluginName$jscomp$inline_221 + injectedNamesToPlugins$jscomp$inline_226.hasOwnProperty( + pluginName$jscomp$inline_228 ) ) { - var pluginModule$jscomp$inline_222 = - injectedNamesToPlugins$jscomp$inline_219[pluginName$jscomp$inline_221]; + var pluginModule$jscomp$inline_229 = + injectedNamesToPlugins$jscomp$inline_226[pluginName$jscomp$inline_228]; if ( - !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_221) || - namesToPlugins[pluginName$jscomp$inline_221] !== - pluginModule$jscomp$inline_222 + !namesToPlugins.hasOwnProperty(pluginName$jscomp$inline_228) || + namesToPlugins[pluginName$jscomp$inline_228] !== + pluginModule$jscomp$inline_229 ) { - if (namesToPlugins[pluginName$jscomp$inline_221]) + if (namesToPlugins[pluginName$jscomp$inline_228]) throw Error( "EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + - pluginName$jscomp$inline_221 + + pluginName$jscomp$inline_228 + "`." ); namesToPlugins[ - pluginName$jscomp$inline_221 - ] = pluginModule$jscomp$inline_222; - isOrderingDirty$jscomp$inline_220 = !0; + pluginName$jscomp$inline_228 + ] = pluginModule$jscomp$inline_229; + isOrderingDirty$jscomp$inline_227 = !0; } } -isOrderingDirty$jscomp$inline_220 && recomputePluginOrdering(); +isOrderingDirty$jscomp$inline_227 && recomputePluginOrdering(); var instanceCache = new Map(), instanceProps = new Map(); function getInstanceFromTag(tag) { @@ -1140,8 +1140,7 @@ var ReactSharedInternals = REACT_LAZY_TYPE = 60116, REACT_DEBUG_TRACING_MODE_TYPE = 60129, REACT_OFFSCREEN_TYPE = 60130, - REACT_LEGACY_HIDDEN_TYPE = 60131, - REACT_CACHE_TYPE = 60132; + REACT_LEGACY_HIDDEN_TYPE = 60131; if ("function" === typeof Symbol && Symbol.for) { var symbolFor = Symbol.for; REACT_ELEMENT_TYPE = symbolFor("react.element"); @@ -1160,7 +1159,6 @@ if ("function" === typeof Symbol && Symbol.for) { REACT_DEBUG_TRACING_MODE_TYPE = symbolFor("react.debug_trace_mode"); REACT_OFFSCREEN_TYPE = symbolFor("react.offscreen"); REACT_LEGACY_HIDDEN_TYPE = symbolFor("react.legacy_hidden"); - REACT_CACHE_TYPE = symbolFor("react.cache"); } var MAYBE_ITERATOR_SYMBOL = "function" === typeof Symbol && Symbol.iterator; function getIteratorFn(maybeIterable) { @@ -1187,8 +1185,6 @@ function getComponentName(type) { return "Suspense"; case REACT_SUSPENSE_LIST_TYPE: return "SuspenseList"; - case REACT_CACHE_TYPE: - return "Cache"; } if ("object" === typeof type) switch (type.$$typeof) { @@ -1222,7 +1218,7 @@ function getNearestMountedFiber(fiber) { fiber = node; do (node = fiber), - 0 !== (node.flags & 2050) && (nearestMounted = node.return), + 0 !== (node.flags & 1026) && (nearestMounted = node.return), (fiber = node.return); while (fiber); } @@ -1310,14 +1306,19 @@ function findCurrentFiberUsingSlowPath(fiber) { } function findCurrentHostFiber(parent) { parent = findCurrentFiberUsingSlowPath(parent); - return null !== parent ? findCurrentHostFiberImpl(parent) : null; -} -function findCurrentHostFiberImpl(node) { - if (5 === node.tag || 6 === node.tag) return node; - for (node = node.child; null !== node; ) { - var match = findCurrentHostFiberImpl(node); - if (null !== match) return match; - node = node.sibling; + if (!parent) return null; + for (var node = parent; ; ) { + if (5 === node.tag || 6 === node.tag) return node; + if (node.child) (node.child.return = node), (node = node.child); + else { + if (node === parent) break; + for (; !node.sibling; ) { + if (!node.return || node.return === parent) return null; + node = node.return; + } + node.sibling.return = node.return; + node = node.sibling; + } } return null; } @@ -1567,220 +1568,249 @@ function mountSafeCallback_NOT_REALLY_SAFE(context, callback) { }; } var ReactNativeFiberHostComponent = (function() { - function ReactNativeFiberHostComponent(tag, viewConfig) { - this._nativeTag = tag; - this._children = []; - this.viewConfig = viewConfig; - } - var _proto = ReactNativeFiberHostComponent.prototype; - _proto.blur = function() { - ReactNativePrivateInterface.TextInputState.blurTextInput(this); - }; - _proto.focus = function() { - ReactNativePrivateInterface.TextInputState.focusTextInput(this); - }; - _proto.measure = function(callback) { - ReactNativePrivateInterface.UIManager.measure( + function ReactNativeFiberHostComponent(tag, viewConfig) { + this._nativeTag = tag; + this._children = []; + this.viewConfig = viewConfig; + } + var _proto = ReactNativeFiberHostComponent.prototype; + _proto.blur = function() { + ReactNativePrivateInterface.TextInputState.blurTextInput(this); + }; + _proto.focus = function() { + ReactNativePrivateInterface.TextInputState.focusTextInput(this); + }; + _proto.measure = function(callback) { + ReactNativePrivateInterface.UIManager.measure( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + _proto.measureInWindow = function(callback) { + ReactNativePrivateInterface.UIManager.measureInWindow( + this._nativeTag, + mountSafeCallback_NOT_REALLY_SAFE(this, callback) + ); + }; + _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { + if ("number" === typeof relativeToNativeNode) + var relativeNode = relativeToNativeNode; + else + relativeToNativeNode._nativeTag && + (relativeNode = relativeToNativeNode._nativeTag); + null != relativeNode && + ReactNativePrivateInterface.UIManager.measureLayout( this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) + relativeNode, + mountSafeCallback_NOT_REALLY_SAFE(this, onFail), + mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) ); - }; - _proto.measureInWindow = function(callback) { - ReactNativePrivateInterface.UIManager.measureInWindow( + }; + _proto.setNativeProps = function(nativeProps) { + nativeProps = diffProperties( + null, + emptyObject, + nativeProps, + this.viewConfig.validAttributes + ); + null != nativeProps && + ReactNativePrivateInterface.UIManager.updateView( this._nativeTag, - mountSafeCallback_NOT_REALLY_SAFE(this, callback) + this.viewConfig.uiViewClassName, + nativeProps ); - }; - _proto.measureLayout = function(relativeToNativeNode, onSuccess, onFail) { - if ("number" === typeof relativeToNativeNode) - var relativeNode = relativeToNativeNode; - else - relativeToNativeNode._nativeTag && - (relativeNode = relativeToNativeNode._nativeTag); - null != relativeNode && - ReactNativePrivateInterface.UIManager.measureLayout( - this._nativeTag, - relativeNode, - mountSafeCallback_NOT_REALLY_SAFE(this, onFail), - mountSafeCallback_NOT_REALLY_SAFE(this, onSuccess) - ); - }; - _proto.setNativeProps = function(nativeProps) { - nativeProps = diffProperties( - null, - emptyObject, - nativeProps, - this.viewConfig.validAttributes - ); - null != nativeProps && - ReactNativePrivateInterface.UIManager.updateView( - this._nativeTag, - this.viewConfig.uiViewClassName, - nativeProps - ); - }; - return ReactNativeFiberHostComponent; - })(), - Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, - Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, - Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, - Scheduler_shouldYield = Scheduler.unstable_shouldYield, - Scheduler_requestPaint = Scheduler.unstable_requestPaint, - Scheduler_now = Scheduler.unstable_now, - Scheduler_getCurrentPriorityLevel = - Scheduler.unstable_getCurrentPriorityLevel, - Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, - Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, - Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, - Scheduler_LowPriority = Scheduler.unstable_LowPriority, - Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) + }; + return ReactNativeFiberHostComponent; +})(); +function shim() { throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." ); -var requestPaint = - void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, - syncQueue = null, - immediateQueueCallbackNode = null, - isFlushingSyncQueue = !1, - initialTimeMs = Scheduler_now(), - now = - 1e4 > initialTimeMs - ? Scheduler_now - : function() { - return Scheduler_now() - initialTimeMs; - }; -function getCurrentPriorityLevel() { - switch (Scheduler_getCurrentPriorityLevel()) { - case Scheduler_ImmediatePriority: - return 99; - case Scheduler_UserBlockingPriority: - return 98; - case Scheduler_NormalPriority: - return 97; - case Scheduler_LowPriority: - return 96; - case Scheduler_IdlePriority: - return 95; - default: - throw Error("Unknown priority level."); - } } -function reactPriorityToSchedulerPriority(reactPriorityLevel) { - switch (reactPriorityLevel) { - case 99: - return Scheduler_ImmediatePriority; - case 98: - return Scheduler_UserBlockingPriority; - case 97: - return Scheduler_NormalPriority; - case 96: - return Scheduler_LowPriority; - case 95: - return Scheduler_IdlePriority; - default: - throw Error("Unknown priority level."); +var getViewConfigForType = + ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, + UPDATE_SIGNAL = {}, + nextReactTag = 3; +function allocateTag() { + var tag = nextReactTag; + 1 === tag % 10 && (tag += 2); + nextReactTag = tag + 2; + return tag; +} +function recursivelyUncacheFiberNode(node) { + if ("number" === typeof node) + instanceCache.delete(node), instanceProps.delete(node); + else { + var tag = node._nativeTag; + instanceCache.delete(tag); + instanceProps.delete(tag); + node._children.forEach(recursivelyUncacheFiberNode); } } -function runWithPriority(reactPriorityLevel, fn) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_runWithPriority(reactPriorityLevel, fn); +function finalizeInitialChildren(parentInstance) { + if (0 === parentInstance._children.length) return !1; + var nativeTags = parentInstance._children.map(function(child) { + return "number" === typeof child ? child : child._nativeTag; + }); + ReactNativePrivateInterface.UIManager.setChildren( + parentInstance._nativeTag, + nativeTags + ); + return !1; } -function scheduleCallback(reactPriorityLevel, callback, options) { - reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); - return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); +var scheduleTimeout = setTimeout, + cancelTimeout = clearTimeout; +function describeComponentFrame(name, source, ownerName) { + source = ""; + ownerName && (source = " (created by " + ownerName + ")"); + return "\n in " + (name || "Unknown") + source; } -function flushSyncCallbackQueue() { - if (null !== immediateQueueCallbackNode) { - var node = immediateQueueCallbackNode; - immediateQueueCallbackNode = null; - Scheduler_cancelCallback(node); - } - flushSyncCallbackQueueImpl(); +function describeFunctionComponentFrame(fn, source) { + return fn + ? describeComponentFrame(fn.displayName || fn.name || null, source, null) + : ""; } -function flushSyncCallbackQueueImpl() { - if (!isFlushingSyncQueue && null !== syncQueue) { - isFlushingSyncQueue = !0; - var i = 0; - try { - var queue = syncQueue; - runWithPriority(99, function() { - for (; i < queue.length; i++) { - var callback = queue[i]; - do callback = callback(!0); - while (null !== callback); - } - }); - syncQueue = null; - } catch (error) { - throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), - Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueue - ), - error); - } finally { - isFlushingSyncQueue = !1; - } - } +var valueStack = [], + index = -1; +function createCursor(defaultValue) { + return { current: defaultValue }; } -var nextTransitionLane = 512, - nextRetryLane = 8388608, - return_highestLanePriority = 8; +function pop(cursor) { + 0 > index || + ((cursor.current = valueStack[index]), (valueStack[index] = null), index--); +} +function push(cursor, value) { + index++; + valueStack[index] = cursor.current; + cursor.current = value; +} +var emptyContextObject = {}, + contextStackCursor = createCursor(emptyContextObject), + didPerformWorkStackCursor = createCursor(!1), + previousContext = emptyContextObject; +function getMaskedContext(workInProgress, unmaskedContext) { + var contextTypes = workInProgress.type.contextTypes; + if (!contextTypes) return emptyContextObject; + var instance = workInProgress.stateNode; + if ( + instance && + instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext + ) + return instance.__reactInternalMemoizedMaskedChildContext; + var context = {}, + key; + for (key in contextTypes) context[key] = unmaskedContext[key]; + instance && + ((workInProgress = workInProgress.stateNode), + (workInProgress.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext), + (workInProgress.__reactInternalMemoizedMaskedChildContext = context)); + return context; +} +function isContextProvider(type) { + type = type.childContextTypes; + return null !== type && void 0 !== type; +} +function popContext() { + pop(didPerformWorkStackCursor); + pop(contextStackCursor); +} +function pushTopLevelContextObject(fiber, context, didChange) { + if (contextStackCursor.current !== emptyContextObject) + throw Error( + "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." + ); + push(contextStackCursor, context); + push(didPerformWorkStackCursor, didChange); +} +function processChildContext(fiber, type, parentContext) { + var instance = fiber.stateNode; + fiber = type.childContextTypes; + if ("function" !== typeof instance.getChildContext) return parentContext; + instance = instance.getChildContext(); + for (var contextKey in instance) + if (!(contextKey in fiber)) + throw Error( + (getComponentName(type) || "Unknown") + + '.getChildContext(): key "' + + contextKey + + '" is not defined in childContextTypes.' + ); + return Object.assign({}, parentContext, instance); +} +function pushContextProvider(workInProgress) { + workInProgress = + ((workInProgress = workInProgress.stateNode) && + workInProgress.__reactInternalMemoizedMergedChildContext) || + emptyContextObject; + previousContext = contextStackCursor.current; + push(contextStackCursor, workInProgress); + push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); + return !0; +} +function invalidateContextProvider(workInProgress, type, didChange) { + var instance = workInProgress.stateNode; + if (!instance) + throw Error( + "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." + ); + didChange + ? ((workInProgress = processChildContext( + workInProgress, + type, + previousContext + )), + (instance.__reactInternalMemoizedMergedChildContext = workInProgress), + pop(didPerformWorkStackCursor), + pop(contextStackCursor), + push(contextStackCursor, workInProgress)) + : pop(didPerformWorkStackCursor); + push(didPerformWorkStackCursor, didChange); +} +var rendererID = null, + injectedHook = null, + isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__, + Scheduler_now = Scheduler.unstable_now; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +Scheduler_now(); +var return_highestLanePriority = 8; function getHighestPriorityLanes(lanes) { - switch (lanes & -lanes) { - case 1: - return (return_highestLanePriority = 15), 1; - case 2: - return (return_highestLanePriority = 14), 2; - case 4: - return (return_highestLanePriority = 13), 4; - case 8: - return (return_highestLanePriority = 12), 8; - case 16: - return (return_highestLanePriority = 11), 16; - case 32: - return (return_highestLanePriority = 10), 32; - case 64: - return (return_highestLanePriority = 9), 64; - case 128: - return (return_highestLanePriority = 8), 128; - case 256: - return (return_highestLanePriority = 7), 256; - case 512: - case 1024: - case 2048: - case 4096: - case 8192: - case 16384: - case 32768: - case 65536: - case 131072: - case 262144: - case 524288: - case 1048576: - case 2097152: - case 4194304: - return (return_highestLanePriority = 6), lanes & 8388096; - case 8388608: - case 16777216: - case 33554432: - case 67108864: - return (return_highestLanePriority = 5), lanes & 125829120; - case 134217728: - return (return_highestLanePriority = 4), 134217728; - case 268435456: - return (return_highestLanePriority = 3), 268435456; - case 536870912: - return (return_highestLanePriority = 2), 536870912; - case 1073741824: - return (return_highestLanePriority = 1), 1073741824; - default: - return (return_highestLanePriority = 8), lanes; - } + if (0 !== (1 & lanes)) return (return_highestLanePriority = 15), 1; + if (0 !== (2 & lanes)) return (return_highestLanePriority = 14), 2; + if (0 !== (4 & lanes)) return (return_highestLanePriority = 13), 4; + var inputDiscreteLanes = 24 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 12), inputDiscreteLanes; + if (0 !== (lanes & 32)) return (return_highestLanePriority = 11), 32; + inputDiscreteLanes = 192 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 10), inputDiscreteLanes; + if (0 !== (lanes & 256)) return (return_highestLanePriority = 9), 256; + inputDiscreteLanes = 3584 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 8), inputDiscreteLanes; + if (0 !== (lanes & 4096)) return (return_highestLanePriority = 7), 4096; + inputDiscreteLanes = 4186112 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 6), inputDiscreteLanes; + inputDiscreteLanes = 62914560 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 5), inputDiscreteLanes; + if (lanes & 67108864) return (return_highestLanePriority = 4), 67108864; + if (0 !== (lanes & 134217728)) + return (return_highestLanePriority = 3), 134217728; + inputDiscreteLanes = 805306368 & lanes; + if (0 !== inputDiscreteLanes) + return (return_highestLanePriority = 2), inputDiscreteLanes; + if (0 !== (1073741824 & lanes)) + return (return_highestLanePriority = 1), 1073741824; + return_highestLanePriority = 8; + return lanes; } function schedulerPriorityToLanePriority(schedulerPriorityLevel) { switch (schedulerPriorityLevel) { @@ -1834,286 +1864,214 @@ function getNextLanes(root, wipLanes) { expiredLanes = root.expiredLanes, suspendedLanes = root.suspendedLanes, pingedLanes = root.pingedLanes; - 0 !== expiredLanes - ? ((nextLanes = expiredLanes), - (nextLanePriority = return_highestLanePriority = 15)) - : ((expiredLanes = pendingLanes & 268435455), + if (0 !== expiredLanes) + (nextLanes = expiredLanes), + (nextLanePriority = return_highestLanePriority = 15); + else if (((expiredLanes = pendingLanes & 134217727), 0 !== expiredLanes)) { + var nonIdleUnblockedLanes = expiredLanes & ~suspendedLanes; + 0 !== nonIdleUnblockedLanes + ? ((nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes)), + (nextLanePriority = return_highestLanePriority)) + : ((pingedLanes &= expiredLanes), + 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority))); + } else + (expiredLanes = pendingLanes & ~suspendedLanes), 0 !== expiredLanes - ? ((pendingLanes = expiredLanes & ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : ((pingedLanes &= expiredLanes), - 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))) - : ((pendingLanes &= ~suspendedLanes), - 0 !== pendingLanes - ? ((nextLanes = getHighestPriorityLanes(pendingLanes)), - (nextLanePriority = return_highestLanePriority)) - : 0 !== pingedLanes && - ((nextLanes = getHighestPriorityLanes(pingedLanes)), - (nextLanePriority = return_highestLanePriority)))); + ? ((nextLanes = getHighestPriorityLanes(expiredLanes)), + (nextLanePriority = return_highestLanePriority)) + : 0 !== pingedLanes && + ((nextLanes = getHighestPriorityLanes(pingedLanes)), + (nextLanePriority = return_highestLanePriority)); if (0 === nextLanes) return 0; + nextLanes = 31 - clz32(nextLanes); + nextLanes = pendingLanes & (((0 > nextLanes ? 0 : 1 << nextLanes) << 1) - 1); if ( 0 !== wipLanes && wipLanes !== nextLanes && 0 === (wipLanes & suspendedLanes) ) { getHighestPriorityLanes(wipLanes); - suspendedLanes = return_highestLanePriority; - if ( - nextLanePriority <= suspendedLanes || - (8 === nextLanePriority && 6 === suspendedLanes) - ) - return wipLanes; + if (nextLanePriority <= return_highestLanePriority) return wipLanes; return_highestLanePriority = nextLanePriority; } wipLanes = root.entangledLanes; if (0 !== wipLanes) for (root = root.entanglements, wipLanes &= nextLanes; 0 < wipLanes; ) - (nextLanePriority = 31 - clz32(wipLanes)), - (suspendedLanes = 1 << nextLanePriority), - (nextLanes |= root[nextLanePriority]), - (wipLanes &= ~suspendedLanes); + (pendingLanes = 31 - clz32(wipLanes)), + (nextLanePriority = 1 << pendingLanes), + (nextLanes |= root[pendingLanes]), + (wipLanes &= ~nextLanePriority); return nextLanes; } function getLanesToRetrySynchronouslyOnError(root) { root = root.pendingLanes & -1073741825; return 0 !== root ? root : root & 1073741824 ? 1073741824 : 0; } -function findUpdateLane(lanePriority) { +function findUpdateLane(lanePriority, wipLanes) { switch (lanePriority) { case 15: return 1; case 14: return 2; case 12: - return 8; + return ( + (lanePriority = getHighestPriorityLane(24 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(10, wipLanes) : lanePriority + ); case 10: - return 32; + return ( + (lanePriority = getHighestPriorityLane(192 & ~wipLanes)), + 0 === lanePriority ? findUpdateLane(8, wipLanes) : lanePriority + ); case 8: - return 128; + return ( + (lanePriority = getHighestPriorityLane(3584 & ~wipLanes)), + 0 === lanePriority && + ((lanePriority = getHighestPriorityLane(4186112 & ~wipLanes)), + 0 === lanePriority && (lanePriority = 512)), + lanePriority + ); case 2: - return 536870912; - } - throw Error( - "Invalid update priority: " + lanePriority + ". This is a bug in React." - ); -} -function createLaneMap(initial) { - for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); - return laneMap; -} -function markRootUpdated(root, updateLane, eventTime) { - root.pendingLanes |= updateLane; - 536870912 !== updateLane && - ((root.suspendedLanes = 0), (root.pingedLanes = 0)); - root = root.eventTimes; - updateLane = 31 - clz32(updateLane); - root[updateLane] = eventTime; -} -function markRootFinished(root, remainingLanes) { - var noLongerPendingLanes = root.pendingLanes & ~remainingLanes; - root.pendingLanes = remainingLanes; - root.suspendedLanes = 0; - root.pingedLanes = 0; - root.expiredLanes &= remainingLanes; - root.mutableReadLanes &= remainingLanes; - root.entangledLanes &= remainingLanes; - remainingLanes = root.entanglements; - var eventTimes = root.eventTimes; - for (root = root.expirationTimes; 0 < noLongerPendingLanes; ) { - var index$8 = 31 - clz32(noLongerPendingLanes), - lane = 1 << index$8; - remainingLanes[index$8] = 0; - eventTimes[index$8] = -1; - root[index$8] = -1; - noLongerPendingLanes &= ~lane; - } -} -function markRootEntangled(root, entangledLanes) { - var rootEntangledLanes = (root.entangledLanes |= entangledLanes); - for (root = root.entanglements; rootEntangledLanes; ) { - var index$9 = 31 - clz32(rootEntangledLanes), - lane = 1 << index$9; - (lane & entangledLanes) | (root[index$9] & entangledLanes) && - (root[index$9] |= entangledLanes); - rootEntangledLanes &= ~lane; - } -} -var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, - log = Math.log, - LN2 = Math.LN2; -function clz32Fallback(lanes) { - return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; -} -var Scheduler_now$1 = Scheduler.unstable_now; -if ( - null == tracing.__interactionsRef || - null == tracing.__interactionsRef.current -) - throw Error( - "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" - ); -Scheduler_now$1(); -function shim() { - throw Error( - "The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue." - ); -} -var getViewConfigForType = - ReactNativePrivateInterface.ReactNativeViewConfigRegistry.get, - UPDATE_SIGNAL = {}, - nextReactTag = 3; -function allocateTag() { - var tag = nextReactTag; - 1 === tag % 10 && (tag += 2); - nextReactTag = tag + 2; - return tag; -} -function recursivelyUncacheFiberNode(node) { - if ("number" === typeof node) - instanceCache.delete(node), instanceProps.delete(node); - else { - var tag = node._nativeTag; - instanceCache.delete(tag); - instanceProps.delete(tag); - node._children.forEach(recursivelyUncacheFiberNode); - } -} -function finalizeInitialChildren(parentInstance) { - if (0 === parentInstance._children.length) return !1; - var nativeTags = parentInstance._children.map(function(child) { - return "number" === typeof child ? child : child._nativeTag; - }); - ReactNativePrivateInterface.UIManager.setChildren( - parentInstance._nativeTag, - nativeTags + return ( + (wipLanes = getHighestPriorityLane(805306368 & ~wipLanes)), + 0 === wipLanes && (wipLanes = 268435456), + wipLanes + ); + } + throw Error( + "Invalid update priority: " + lanePriority + ". This is a bug in React." ); - return !1; -} -var scheduleTimeout = setTimeout, - cancelTimeout = clearTimeout; -function describeComponentFrame(name, source, ownerName) { - source = ""; - ownerName && (source = " (created by " + ownerName + ")"); - return "\n in " + (name || "Unknown") + source; -} -function describeFunctionComponentFrame(fn, source) { - return fn - ? describeComponentFrame(fn.displayName || fn.name || null, source, null) - : ""; } -var valueStack = [], - index = -1; -function createCursor(defaultValue) { - return { current: defaultValue }; -} -function pop(cursor) { - 0 > index || - ((cursor.current = valueStack[index]), (valueStack[index] = null), index--); +function getHighestPriorityLane(lanes) { + return lanes & -lanes; } -function push(cursor, value) { - index++; - valueStack[index] = cursor.current; - cursor.current = value; +function createLaneMap(initial) { + for (var laneMap = [], i = 0; 31 > i; i++) laneMap.push(initial); + return laneMap; } -var emptyContextObject = {}, - contextStackCursor = createCursor(emptyContextObject), - didPerformWorkStackCursor = createCursor(!1), - previousContext = emptyContextObject; -function getMaskedContext(workInProgress, unmaskedContext) { - var contextTypes = workInProgress.type.contextTypes; - if (!contextTypes) return emptyContextObject; - var instance = workInProgress.stateNode; - if ( - instance && - instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext - ) - return instance.__reactInternalMemoizedMaskedChildContext; - var context = {}, - key; - for (key in contextTypes) context[key] = unmaskedContext[key]; - instance && - ((workInProgress = workInProgress.stateNode), - (workInProgress.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext), - (workInProgress.__reactInternalMemoizedMaskedChildContext = context)); - return context; +function markRootUpdated(root, updateLane, eventTime) { + root.pendingLanes |= updateLane; + var higherPriorityLanes = updateLane - 1; + root.suspendedLanes &= higherPriorityLanes; + root.pingedLanes &= higherPriorityLanes; + root = root.eventTimes; + updateLane = 31 - clz32(updateLane); + root[updateLane] = eventTime; } -function isContextProvider(type) { - type = type.childContextTypes; - return null !== type && void 0 !== type; +var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback, + log = Math.log, + LN2 = Math.LN2; +function clz32Fallback(lanes) { + return 0 === lanes ? 32 : (31 - ((log(lanes) / LN2) | 0)) | 0; } -function popContext() { - pop(didPerformWorkStackCursor); - pop(contextStackCursor); +var Scheduler_runWithPriority = Scheduler.unstable_runWithPriority, + Scheduler_scheduleCallback = Scheduler.unstable_scheduleCallback, + Scheduler_cancelCallback = Scheduler.unstable_cancelCallback, + Scheduler_shouldYield = Scheduler.unstable_shouldYield, + Scheduler_requestPaint = Scheduler.unstable_requestPaint, + Scheduler_now$1 = Scheduler.unstable_now, + Scheduler_getCurrentPriorityLevel = + Scheduler.unstable_getCurrentPriorityLevel, + Scheduler_ImmediatePriority = Scheduler.unstable_ImmediatePriority, + Scheduler_UserBlockingPriority = Scheduler.unstable_UserBlockingPriority, + Scheduler_NormalPriority = Scheduler.unstable_NormalPriority, + Scheduler_LowPriority = Scheduler.unstable_LowPriority, + Scheduler_IdlePriority = Scheduler.unstable_IdlePriority; +if ( + null == tracing.__interactionsRef || + null == tracing.__interactionsRef.current +) + throw Error( + "It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at https://reactjs.org/link/profiling" + ); +var fakeCallbackNode = {}, + requestPaint = + void 0 !== Scheduler_requestPaint ? Scheduler_requestPaint : function() {}, + syncQueue = null, + immediateQueueCallbackNode = null, + isFlushingSyncQueue = !1, + initialTimeMs$1 = Scheduler_now$1(), + now = + 1e4 > initialTimeMs$1 + ? Scheduler_now$1 + : function() { + return Scheduler_now$1() - initialTimeMs$1; + }; +function getCurrentPriorityLevel() { + switch (Scheduler_getCurrentPriorityLevel()) { + case Scheduler_ImmediatePriority: + return 99; + case Scheduler_UserBlockingPriority: + return 98; + case Scheduler_NormalPriority: + return 97; + case Scheduler_LowPriority: + return 96; + case Scheduler_IdlePriority: + return 95; + default: + throw Error("Unknown priority level."); + } } -function pushTopLevelContextObject(fiber, context, didChange) { - if (contextStackCursor.current !== emptyContextObject) - throw Error( - "Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue." - ); - push(contextStackCursor, context); - push(didPerformWorkStackCursor, didChange); +function reactPriorityToSchedulerPriority(reactPriorityLevel) { + switch (reactPriorityLevel) { + case 99: + return Scheduler_ImmediatePriority; + case 98: + return Scheduler_UserBlockingPriority; + case 97: + return Scheduler_NormalPriority; + case 96: + return Scheduler_LowPriority; + case 95: + return Scheduler_IdlePriority; + default: + throw Error("Unknown priority level."); + } } -function processChildContext(fiber, type, parentContext) { - var instance = fiber.stateNode; - fiber = type.childContextTypes; - if ("function" !== typeof instance.getChildContext) return parentContext; - instance = instance.getChildContext(); - for (var contextKey in instance) - if (!(contextKey in fiber)) - throw Error( - (getComponentName(type) || "Unknown") + - '.getChildContext(): key "' + - contextKey + - '" is not defined in childContextTypes.' - ); - return Object.assign({}, parentContext, instance); +function runWithPriority(reactPriorityLevel, fn) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_runWithPriority(reactPriorityLevel, fn); } -function pushContextProvider(workInProgress) { - workInProgress = - ((workInProgress = workInProgress.stateNode) && - workInProgress.__reactInternalMemoizedMergedChildContext) || - emptyContextObject; - previousContext = contextStackCursor.current; - push(contextStackCursor, workInProgress); - push(didPerformWorkStackCursor, didPerformWorkStackCursor.current); - return !0; +function scheduleCallback(reactPriorityLevel, callback, options) { + reactPriorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel); + return Scheduler_scheduleCallback(reactPriorityLevel, callback, options); } -function invalidateContextProvider(workInProgress, type, didChange) { - var instance = workInProgress.stateNode; - if (!instance) - throw Error( - "Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue." - ); - didChange - ? ((workInProgress = processChildContext( - workInProgress, - type, - previousContext - )), - (instance.__reactInternalMemoizedMergedChildContext = workInProgress), - pop(didPerformWorkStackCursor), - pop(contextStackCursor), - push(contextStackCursor, workInProgress)) - : pop(didPerformWorkStackCursor); - push(didPerformWorkStackCursor, didChange); +function flushSyncCallbackQueue() { + if (null !== immediateQueueCallbackNode) { + var node = immediateQueueCallbackNode; + immediateQueueCallbackNode = null; + Scheduler_cancelCallback(node); + } + flushSyncCallbackQueueImpl(); } -var rendererID = null, - injectedHook = null, - isDevToolsPresent = "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__; -function onCommitRoot(root, priorityLevel) { - if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) +function flushSyncCallbackQueueImpl() { + if (!isFlushingSyncQueue && null !== syncQueue) { + isFlushingSyncQueue = !0; + var i = 0; try { - injectedHook.onCommitFiberRoot( - rendererID, - root, - priorityLevel, - 128 === (root.current.flags & 128) - ); - } catch (err) {} + var queue = syncQueue; + runWithPriority(99, function() { + for (; i < queue.length; i++) { + var callback = queue[i]; + do callback = callback(!0); + while (null !== callback); + } + }); + syncQueue = null; + } catch (error) { + throw (null !== syncQueue && (syncQueue = syncQueue.slice(i + 1)), + Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueue + ), + error); + } finally { + isFlushingSyncQueue = !1; + } + } } var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; function is(x, y) { @@ -2193,10 +2151,10 @@ var valueCursor = createCursor(null), function resetContextDependencies() { lastContextWithAllBitsObserved = lastContextDependency = currentlyRenderingFiber = null; } -function popProvider(context) { +function popProvider(providerFiber) { var currentValue = valueCursor.current; pop(valueCursor); - context._currentValue = currentValue; + providerFiber.type._context._currentValue = currentValue; } function scheduleWorkOnParentPath(parent, renderLanes) { for (; null !== parent; ) { @@ -2247,14 +2205,13 @@ function readContext(context, observedBits) { } return context._currentValue; } -var interleavedQueues = null, - hasForceUpdate = !1; +var hasForceUpdate = !1; function initializeUpdateQueue(fiber) { fiber.updateQueue = { baseState: fiber.memoizedState, firstBaseUpdate: null, lastBaseUpdate: null, - shared: { pending: null, interleaved: null, lanes: 0 }, + shared: { pending: null }, effects: null }; } @@ -2280,32 +2237,14 @@ function createUpdate(eventTime, lane) { }; } function enqueueUpdate(fiber, update) { - var updateQueue = fiber.updateQueue; - null !== updateQueue && - ((updateQueue = updateQueue.shared), - null !== workInProgressRoot && 0 !== (fiber.mode & 1) - ? ((fiber = updateQueue.interleaved), - null === fiber - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [updateQueue]) - : interleavedQueues.push(updateQueue)) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.interleaved = update)) - : ((fiber = updateQueue.pending), - null === fiber - ? (update.next = update) - : ((update.next = fiber.next), (fiber.next = update)), - (updateQueue.pending = update))); -} -function entangleTransitions(root, fiber, lane) { fiber = fiber.updateQueue; - if (null !== fiber && ((fiber = fiber.shared), 0 !== (lane & 8388096))) { - var queueLanes = fiber.lanes; - queueLanes &= root.pendingLanes; - lane |= queueLanes; - fiber.lanes = lane; - markRootEntangled(root, lane); + if (null !== fiber) { + fiber = fiber.shared; + var pending = fiber.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + fiber.pending = update; } } function enqueueCapturedUpdate(workInProgress, capturedUpdate) { @@ -2374,110 +2313,111 @@ function processUpdateQueue( : (lastBaseUpdate.next = firstPendingUpdate); lastBaseUpdate = lastPendingUpdate; var current = workInProgress$jscomp$0.alternate; - null !== current && - ((current = current.updateQueue), - (pendingQueue = current.lastBaseUpdate), - pendingQueue !== lastBaseUpdate && - (null === pendingQueue + if (null !== current) { + current = current.updateQueue; + var currentLastBaseUpdate = current.lastBaseUpdate; + currentLastBaseUpdate !== lastBaseUpdate && + (null === currentLastBaseUpdate ? (current.firstBaseUpdate = firstPendingUpdate) - : (pendingQueue.next = firstPendingUpdate), - (current.lastBaseUpdate = lastPendingUpdate))); + : (currentLastBaseUpdate.next = firstPendingUpdate), + (current.lastBaseUpdate = lastPendingUpdate)); + } } if (null !== firstBaseUpdate) { - var newState = queue.baseState; + currentLastBaseUpdate = queue.baseState; lastBaseUpdate = 0; current = firstPendingUpdate = lastPendingUpdate = null; - pendingQueue = firstBaseUpdate; do { - var updateLane = pendingQueue.lane, - updateEventTime = pendingQueue.eventTime; - if ((renderLanes & updateLane) === updateLane) { + pendingQueue = firstBaseUpdate.lane; + var updateEventTime = firstBaseUpdate.eventTime; + if ((renderLanes & pendingQueue) === pendingQueue) { null !== current && (current = current.next = { eventTime: updateEventTime, lane: 0, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }); a: { var workInProgress = workInProgress$jscomp$0, - update = pendingQueue; - updateLane = props; + update = firstBaseUpdate; + pendingQueue = props; updateEventTime = instance; switch (update.tag) { case 1: workInProgress = update.payload; if ("function" === typeof workInProgress) { - newState = workInProgress.call( + currentLastBaseUpdate = workInProgress.call( updateEventTime, - newState, - updateLane + currentLastBaseUpdate, + pendingQueue ); break a; } - newState = workInProgress; + currentLastBaseUpdate = workInProgress; break a; case 3: - workInProgress.flags = (workInProgress.flags & -16385) | 128; + workInProgress.flags = (workInProgress.flags & -8193) | 64; case 0: workInProgress = update.payload; - updateLane = + pendingQueue = "function" === typeof workInProgress - ? workInProgress.call(updateEventTime, newState, updateLane) + ? workInProgress.call( + updateEventTime, + currentLastBaseUpdate, + pendingQueue + ) : workInProgress; - if (null === updateLane || void 0 === updateLane) break a; - newState = Object.assign({}, newState, updateLane); + if (null === pendingQueue || void 0 === pendingQueue) break a; + currentLastBaseUpdate = Object.assign( + {}, + currentLastBaseUpdate, + pendingQueue + ); break a; case 2: hasForceUpdate = !0; } } - null !== pendingQueue.callback && - ((workInProgress$jscomp$0.flags |= 64), - (updateLane = queue.effects), - null === updateLane - ? (queue.effects = [pendingQueue]) - : updateLane.push(pendingQueue)); + null !== firstBaseUpdate.callback && + ((workInProgress$jscomp$0.flags |= 32), + (pendingQueue = queue.effects), + null === pendingQueue + ? (queue.effects = [firstBaseUpdate]) + : pendingQueue.push(firstBaseUpdate)); } else (updateEventTime = { eventTime: updateEventTime, - lane: updateLane, - tag: pendingQueue.tag, - payload: pendingQueue.payload, - callback: pendingQueue.callback, + lane: pendingQueue, + tag: firstBaseUpdate.tag, + payload: firstBaseUpdate.payload, + callback: firstBaseUpdate.callback, next: null }), null === current ? ((firstPendingUpdate = current = updateEventTime), - (lastPendingUpdate = newState)) + (lastPendingUpdate = currentLastBaseUpdate)) : (current = current.next = updateEventTime), - (lastBaseUpdate |= updateLane); - pendingQueue = pendingQueue.next; - if (null === pendingQueue) + (lastBaseUpdate |= pendingQueue); + firstBaseUpdate = firstBaseUpdate.next; + if (null === firstBaseUpdate) if (((pendingQueue = queue.shared.pending), null === pendingQueue)) break; else - (updateLane = pendingQueue), - (pendingQueue = updateLane.next), - (updateLane.next = null), - (queue.lastBaseUpdate = updateLane), + (firstBaseUpdate = pendingQueue.next), + (pendingQueue.next = null), + (queue.lastBaseUpdate = pendingQueue), (queue.shared.pending = null); } while (1); - null === current && (lastPendingUpdate = newState); + null === current && (lastPendingUpdate = currentLastBaseUpdate); queue.baseState = lastPendingUpdate; queue.firstBaseUpdate = firstPendingUpdate; queue.lastBaseUpdate = current; - props = queue.shared.interleaved; - if (null !== props) { - queue = props; - do (lastBaseUpdate |= queue.lane), (queue = queue.next); - while (queue !== props); - } else null === firstBaseUpdate && (queue.shared.lanes = 0); workInProgressRootSkippedLanes |= lastBaseUpdate; workInProgress$jscomp$0.lanes = lastBaseUpdate; - workInProgress$jscomp$0.memoizedState = newState; + workInProgress$jscomp$0.memoizedState = currentLastBaseUpdate; } } function commitUpdateQueue(finishedWork, finishedQueue, instance) { @@ -2533,8 +2473,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueReplaceState: function(inst, payload, callback) { inst = inst._reactInternals; @@ -2545,8 +2484,7 @@ var classComponentUpdater = { update.payload = payload; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - payload = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== payload && entangleTransitions(payload, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); }, enqueueForceUpdate: function(inst, callback) { inst = inst._reactInternals; @@ -2556,8 +2494,7 @@ var classComponentUpdater = { update.tag = 2; void 0 !== callback && null !== callback && (update.callback = callback); enqueueUpdate(inst, update); - callback = scheduleUpdateOnFiber(inst, lane, eventTime); - null !== callback && entangleTransitions(callback, inst, lane); + scheduleUpdateOnFiber(inst, lane, eventTime); } }; function checkShouldComponentUpdate( @@ -2705,22 +2642,24 @@ function coerceRef(returnFiber, current, element) { } function throwOnInvalidObjectType(returnFiber, newChild) { if ("textarea" !== returnFiber.type) - throw ((returnFiber = Object.prototype.toString.call(newChild)), - Error( + throw Error( "Objects are not valid as a React child (found: " + - ("[object Object]" === returnFiber + ("[object Object]" === Object.prototype.toString.call(newChild) ? "object with keys {" + Object.keys(newChild).join(", ") + "}" - : returnFiber) + + : newChild) + "). If you meant to render a collection of children, use an array instead." - )); + ); } function ChildReconciler(shouldTrackSideEffects) { function deleteChild(returnFiber, childToDelete) { if (shouldTrackSideEffects) { - var deletions = returnFiber.deletions; - null === deletions - ? ((returnFiber.deletions = [childToDelete]), (returnFiber.flags |= 16)) - : deletions.push(childToDelete); + var last = returnFiber.lastEffect; + null !== last + ? ((last.nextEffect = childToDelete), + (returnFiber.lastEffect = childToDelete)) + : (returnFiber.firstEffect = returnFiber.lastEffect = childToDelete); + childToDelete.nextEffect = null; + childToDelete.flags = 8; } } function deleteRemainingChildren(returnFiber, currentFirstChild) { @@ -2752,16 +2691,16 @@ function ChildReconciler(shouldTrackSideEffects) { return ( (newIndex = newIndex.index), newIndex < lastPlacedIndex - ? ((newFiber.flags |= 2), lastPlacedIndex) + ? ((newFiber.flags = 2), lastPlacedIndex) : newIndex ); - newFiber.flags |= 2; + newFiber.flags = 2; return lastPlacedIndex; } function placeSingleChild(newFiber) { shouldTrackSideEffects && null === newFiber.alternate && - (newFiber.flags |= 2); + (newFiber.flags = 2); return newFiber; } function updateTextNode(returnFiber, current, textContent, lanes) { @@ -2776,16 +2715,7 @@ function ChildReconciler(shouldTrackSideEffects) { return current; } function updateElement(returnFiber, current, element, lanes) { - var elementType = element.type; - if (elementType === REACT_FRAGMENT_TYPE) - return updateFragment( - returnFiber, - current, - element.props.children, - lanes, - element.key - ); - if (null !== current && current.elementType === elementType) + if (null !== current && current.elementType === element.type) return ( (lanes = useFiber(current, element.props)), (lanes.ref = coerceRef(returnFiber, current, element)), @@ -2899,7 +2829,15 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: return newChild.key === key - ? updateElement(returnFiber, oldFiber, newChild, lanes) + ? newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + oldFiber, + newChild.props.children, + lanes, + key + ) + : updateElement(returnFiber, oldFiber, newChild, lanes) : null; case REACT_PORTAL_TYPE: return newChild.key === key @@ -2934,7 +2872,15 @@ function ChildReconciler(shouldTrackSideEffects) { existingChildren.get( null === newChild.key ? newIdx : newChild.key ) || null), - updateElement(returnFiber, existingChildren, newChild, lanes) + newChild.type === REACT_FRAGMENT_TYPE + ? updateFragment( + returnFiber, + existingChildren, + newChild.props.children, + lanes, + newChild.key + ) + : updateElement(returnFiber, existingChildren, newChild, lanes) ); case REACT_PORTAL_TYPE: return ( @@ -3133,45 +3079,50 @@ function ChildReconciler(shouldTrackSideEffects) { switch (newChild.$$typeof) { case REACT_ELEMENT_TYPE: a: { - isObject = newChild.key; - for ( - isUnkeyedTopLevelFragment = currentFirstChild; - null !== isUnkeyedTopLevelFragment; - - ) { - if (isUnkeyedTopLevelFragment.key === isObject) { - isObject = newChild.type; - if (isObject === REACT_FRAGMENT_TYPE) { - if (7 === isUnkeyedTopLevelFragment.tag) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props.children - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; - } - } else if (isUnkeyedTopLevelFragment.elementType === isObject) { - deleteRemainingChildren( - returnFiber, - isUnkeyedTopLevelFragment.sibling - ); - currentFirstChild = useFiber( - isUnkeyedTopLevelFragment, - newChild.props - ); - currentFirstChild.ref = coerceRef( - returnFiber, - isUnkeyedTopLevelFragment, - newChild - ); - currentFirstChild.return = returnFiber; - returnFiber = currentFirstChild; - break a; + isObject = newChild.key; + for ( + isUnkeyedTopLevelFragment = currentFirstChild; + null !== isUnkeyedTopLevelFragment; + + ) { + if (isUnkeyedTopLevelFragment.key === isObject) { + switch (isUnkeyedTopLevelFragment.tag) { + case 7: + if (newChild.type === REACT_FRAGMENT_TYPE) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props.children + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } + break; + default: + if ( + isUnkeyedTopLevelFragment.elementType === newChild.type + ) { + deleteRemainingChildren( + returnFiber, + isUnkeyedTopLevelFragment.sibling + ); + currentFirstChild = useFiber( + isUnkeyedTopLevelFragment, + newChild.props + ); + currentFirstChild.ref = coerceRef( + returnFiber, + isUnkeyedTopLevelFragment, + newChild + ); + currentFirstChild.return = returnFiber; + returnFiber = currentFirstChild; + break a; + } } deleteRemainingChildren(returnFiber, isUnkeyedTopLevelFragment); break; @@ -3349,7 +3300,7 @@ function findFirstSuspended(row) { if (null !== state && (null === state.dehydrated || shim() || shim())) return node; } else if (19 === node.tag && void 0 !== node.memoizedProps.revealOrder) { - if (0 !== (node.flags & 128)) return node; + if (0 !== (node.flags & 64)) return node; } else if (null !== node.child) { node.child.return = node; node = node.child; @@ -3501,11 +3452,10 @@ function updateReducer(reducer) { queue.pending = null; } if (null !== baseQueue) { - pendingQueue = baseQueue.next; + baseQueue = baseQueue.next; current = current.baseState; - var newBaseQueueFirst = (baseFirst = null), - newBaseQueueLast = null, - update = pendingQueue; + var newBaseQueueLast = (baseFirst = pendingQueue = null), + update = baseQueue; do { var updateLane = update.lane; if ((renderLanes & updateLane) === updateLane) @@ -3530,33 +3480,22 @@ function updateReducer(reducer) { next: null }; null === newBaseQueueLast - ? ((newBaseQueueFirst = newBaseQueueLast = clone), - (baseFirst = current)) + ? ((baseFirst = newBaseQueueLast = clone), (pendingQueue = current)) : (newBaseQueueLast = newBaseQueueLast.next = clone); currentlyRenderingFiber$1.lanes |= updateLane; workInProgressRootSkippedLanes |= updateLane; } update = update.next; - } while (null !== update && update !== pendingQueue); + } while (null !== update && update !== baseQueue); null === newBaseQueueLast - ? (baseFirst = current) - : (newBaseQueueLast.next = newBaseQueueFirst); + ? (pendingQueue = current) + : (newBaseQueueLast.next = baseFirst); objectIs(current, hook.memoizedState) || (didReceiveUpdate = !0); hook.memoizedState = current; - hook.baseState = baseFirst; + hook.baseState = pendingQueue; hook.baseQueue = newBaseQueueLast; queue.lastRenderedState = current; } - reducer = queue.interleaved; - if (null !== reducer) { - baseQueue = reducer; - do - (pendingQueue = baseQueue.lane), - (currentlyRenderingFiber$1.lanes |= pendingQueue), - (workInProgressRootSkippedLanes |= pendingQueue), - (baseQueue = baseQueue.next); - while (baseQueue !== reducer); - } else null === baseQueue && (queue.lanes = 0); return [hook.memoizedState, queue.dispatch]; } function rerenderReducer(reducer) { @@ -3596,7 +3535,7 @@ function readFromUnsubcribedMutableSource(root, source, getSnapshot) { if (root) return getSnapshot(source._source); workInProgressSources.push(source); throw Error( - "Cannot read from mutable source during the current render without tearing. This may be a bug in React. Please file an issue." + "Cannot read from mutable source during the current render without tearing. This is a bug in React. Please file an issue." ); } function useMutableSource(hook, source, getSnapshot, subscribe) { @@ -3626,13 +3565,25 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { refs.getSnapshot = getSnapshot; refs.setSnapshot = setSnapshot; var maybeNewVersion = getVersion(source._source); - objectIs(version, maybeNewVersion) || - ((maybeNewVersion = getSnapshot(source._source)), + if (!objectIs(version, maybeNewVersion)) { + maybeNewVersion = getSnapshot(source._source); objectIs(snapshot, maybeNewVersion) || (setSnapshot(maybeNewVersion), (maybeNewVersion = requestUpdateLane(fiber)), - (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)), - markRootEntangled(root, root.mutableReadLanes)); + (root.mutableReadLanes |= maybeNewVersion & root.pendingLanes)); + maybeNewVersion = root.mutableReadLanes; + root.entangledLanes |= maybeNewVersion; + for ( + var entanglements = root.entanglements, lanes = maybeNewVersion; + 0 < lanes; + + ) { + var index$13 = 31 - clz32(lanes), + lane = 1 << index$13; + entanglements[index$13] |= maybeNewVersion; + lanes &= ~lane; + } + } }, [getSnapshot, source, subscribe] ); @@ -3659,8 +3610,6 @@ function useMutableSource(hook, source, getSnapshot, subscribe) { objectIs(memoizedState, subscribe)) || ((hook = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: snapshot @@ -3686,8 +3635,6 @@ function mountState(initialState) { hook.memoizedState = hook.baseState = initialState; initialState = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: basicStateReducer, lastRenderedState: initialState @@ -3736,7 +3683,7 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { var prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; if (null !== deps && areHookInputsEqual(deps, prevEffect.deps)) { - hook.memoizedState = pushEffect(hookFlags, create, destroy, deps); + pushEffect(hookFlags, create, destroy, deps); return; } } @@ -3744,10 +3691,10 @@ function updateEffectImpl(fiberFlags, hookFlags, create, deps) { hook.memoizedState = pushEffect(1 | hookFlags, create, destroy, deps); } function mountEffect(create, deps) { - return mountEffectImpl(132096, 4, create, deps); + return mountEffectImpl(516, 4, create, deps); } function updateEffect(create, deps) { - return updateEffectImpl(1024, 4, create, deps); + return updateEffectImpl(516, 4, create, deps); } function updateLayoutEffect(create, deps) { return updateEffectImpl(4, 2, create, deps); @@ -3832,55 +3779,33 @@ function dispatchAction(fiber, queue, action) { eagerState: null, next: null }, - alternate = fiber.alternate; + pending = queue.pending; + null === pending + ? (update.next = update) + : ((update.next = pending.next), (pending.next = update)); + queue.pending = update; + pending = fiber.alternate; if ( fiber === currentlyRenderingFiber$1 || - (null !== alternate && alternate === currentlyRenderingFiber$1) + (null !== pending && pending === currentlyRenderingFiber$1) ) - (didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0), - (lane = queue.pending), - null === lane - ? (update.next = update) - : ((update.next = lane.next), (lane.next = update)), - (queue.pending = update); + didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = !0; else { - if (null !== workInProgressRoot && 0 !== (fiber.mode & 1)) { - var interleaved = queue.interleaved; - null === interleaved - ? ((update.next = update), - null === interleavedQueues - ? (interleavedQueues = [queue]) - : interleavedQueues.push(queue)) - : ((update.next = interleaved.next), (interleaved.next = update)); - queue.interleaved = update; - } else - (interleaved = queue.pending), - null === interleaved - ? (update.next = update) - : ((update.next = interleaved.next), (interleaved.next = update)), - (queue.pending = update); if ( 0 === fiber.lanes && - (null === alternate || 0 === alternate.lanes) && - ((alternate = queue.lastRenderedReducer), null !== alternate) + (null === pending || 0 === pending.lanes) && + ((pending = queue.lastRenderedReducer), null !== pending) ) try { var currentState = queue.lastRenderedState, - eagerState = alternate(currentState, action); - update.eagerReducer = alternate; + eagerState = pending(currentState, action); + update.eagerReducer = pending; update.eagerState = eagerState; if (objectIs(eagerState, currentState)) return; } catch (error) { } finally { } - update = scheduleUpdateOnFiber(fiber, lane, eventTime); - 0 !== (lane & 8388096) && - null !== update && - ((fiber = queue.lanes), - (fiber &= update.pendingLanes), - (lane |= fiber), - (queue.lanes = lane), - markRootEntangled(update, lane)); + scheduleUpdateOnFiber(fiber, lane, eventTime); } } var ContextOnlyDispatcher = { @@ -3937,8 +3862,6 @@ var ContextOnlyDispatcher = { hook.memoizedState = hook.baseState = initialArg; reducer = hook.queue = { pending: null, - interleaved: null, - lanes: 0, dispatch: null, lastRenderedReducer: reducer, lastRenderedState: initialArg @@ -4129,7 +4052,7 @@ function updateForwardRef( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4205,15 +4128,14 @@ function updateSimpleMemoComponent( null !== current && shallowEqual(current.memoizedProps, nextProps) && current.ref === workInProgress.ref - ) { - didReceiveUpdate = !1; - if (0 === (renderLanes & updateLanes)) + ) + if (((didReceiveUpdate = !1), 0 !== (renderLanes & updateLanes))) + 0 !== (current.flags & 32768) && (didReceiveUpdate = !0); + else return ( (workInProgress.lanes = current.lanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); - 0 !== (current.flags & 65536) && (didReceiveUpdate = !0); - } return updateFunctionComponent( current, workInProgress, @@ -4230,40 +4152,31 @@ function updateOffscreenComponent(current, workInProgress, renderLanes) { "hidden" === nextProps.mode || "unstable-defer-without-hiding" === nextProps.mode ) - if (0 === (workInProgress.mode & 2)) - (workInProgress.memoizedState = { baseLanes: 0, cachePool: null }), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= renderLanes); - else { - if (0 === (renderLanes & 1073741824)) - return ( - (current = - null !== prevState - ? prevState.baseLanes | renderLanes - : renderLanes), - markSpawnedWork(1073741824), - (workInProgress.lanes = workInProgress.childLanes = 1073741824), - (workInProgress.memoizedState = { - baseLanes: current, - cachePool: null - }), - (workInProgress.updateQueue = null), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= current), - null + if (0 === (workInProgress.mode & 4)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes(workInProgress, renderLanes); + else if (0 !== (renderLanes & 1073741824)) + (workInProgress.memoizedState = { baseLanes: 0 }), + pushRenderLanes( + workInProgress, + null !== prevState ? prevState.baseLanes : renderLanes ); - workInProgress.memoizedState = { baseLanes: 0, cachePool: null }; - nextProps = null !== prevState ? prevState.baseLanes : renderLanes; - push(subtreeRenderLanesCursor, subtreeRenderLanes); - subtreeRenderLanes |= nextProps; - } + else + return ( + (current = + null !== prevState ? prevState.baseLanes | renderLanes : renderLanes), + markSpawnedWork(1073741824), + (workInProgress.lanes = workInProgress.childLanes = 1073741824), + (workInProgress.memoizedState = { baseLanes: current }), + pushRenderLanes(workInProgress, current), + null + ); else null !== prevState ? ((nextProps = prevState.baseLanes | renderLanes), (workInProgress.memoizedState = null)) : (nextProps = renderLanes), - push(subtreeRenderLanesCursor, subtreeRenderLanes), - (subtreeRenderLanes |= nextProps); + pushRenderLanes(workInProgress, nextProps); reconcileChildren(current, workInProgress, nextChildren, renderLanes); return workInProgress.child; } @@ -4273,7 +4186,7 @@ function markRef(current, workInProgress) { (null === current && null !== ref) || (null !== current && current.ref !== ref) ) - workInProgress.flags |= 256; + workInProgress.flags |= 128; } function updateFunctionComponent( current, @@ -4298,7 +4211,7 @@ function updateFunctionComponent( if (null !== current && !didReceiveUpdate) return ( (workInProgress.updateQueue = current.updateQueue), - (workInProgress.flags &= -1029), + (workInProgress.flags &= -517), (current.lanes &= ~renderLanes), bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) ); @@ -4473,7 +4386,7 @@ function updateClassComponent( "function" === typeof instance.componentDidUpdate && (workInProgress.flags |= 4), "function" === typeof instance.getSnapshotBeforeUpdate && - (workInProgress.flags |= 512)) + (workInProgress.flags |= 256)) : ("function" !== typeof instance.componentDidUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || @@ -4481,7 +4394,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (workInProgress.memoizedProps = nextProps), (workInProgress.memoizedState = newState)), (instance.props = nextProps), @@ -4495,7 +4408,7 @@ function updateClassComponent( "function" !== typeof instance.getSnapshotBeforeUpdate || (oldProps === current.memoizedProps && oldState === current.memoizedState) || - (workInProgress.flags |= 512), + (workInProgress.flags |= 256), (nextProps = !1)); } return finishClassComponent( @@ -4516,7 +4429,7 @@ function finishClassComponent( renderLanes ) { markRef(current, workInProgress); - var didCaptureError = 0 !== (workInProgress.flags & 128); + var didCaptureError = 0 !== (workInProgress.flags & 64); if (!shouldUpdate && !didCaptureError) return ( hasContext && invalidateContextProvider(workInProgress, Component, !1), @@ -4564,21 +4477,18 @@ function pushHostRootContext(workInProgress) { 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 = 0 !== (workInProgress.flags & 64)) || (JSCompiler_temp = null !== current && null === current.memoizedState ? !1 : 0 !== (suspenseContext & 2)); JSCompiler_temp - ? ((showFallback = !0), (workInProgress.flags &= -129)) + ? ((showFallback = !0), (workInProgress.flags &= -65)) : (null !== current && null === current.memoizedState) || void 0 === nextProps.fallback || !0 === nextProps.unstable_avoidThisFallback || @@ -4595,9 +4505,7 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), current ); @@ -4609,12 +4517,10 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { suspenseContext, renderLanes )), - (workInProgress.child.memoizedState = mountSuspenseOffscreenState( - renderLanes - )), + (workInProgress.child.memoizedState = { baseLanes: renderLanes }), (workInProgress.memoizedState = SUSPENDED_MARKER), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432), current ); renderLanes = createFiberFromOffscreen( @@ -4640,11 +4546,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4671,11 +4574,8 @@ function updateSuspenseComponent(current, workInProgress, renderLanes) { (suspenseContext = current.child.memoizedState), (showFallback.memoizedState = null === suspenseContext - ? mountSuspenseOffscreenState(renderLanes) - : { - baseLanes: suspenseContext.baseLanes | renderLanes, - cachePool: null - }), + ? { baseLanes: renderLanes } + : { baseLanes: suspenseContext.baseLanes | renderLanes }), (showFallback.childLanes = current.childLanes & ~renderLanes), (workInProgress.memoizedState = SUSPENDED_MARKER), nextProps @@ -4698,10 +4598,10 @@ function mountSuspenseFallbackChildren( var mode = workInProgress.mode, progressedPrimaryFragment = workInProgress.child; primaryChildren = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && null !== progressedPrimaryFragment + 0 === (mode & 2) && null !== progressedPrimaryFragment ? ((progressedPrimaryFragment.childLanes = 0), (progressedPrimaryFragment.pendingProps = primaryChildren), - workInProgress.mode & 4 && + workInProgress.mode & 8 && ((progressedPrimaryFragment.actualDuration = 0), (progressedPrimaryFragment.actualStartTime = -1), (progressedPrimaryFragment.selfBaseDuration = 0), @@ -4736,14 +4636,13 @@ function updateSuspensePrimaryChildren( mode: "visible", children: primaryChildren }); - 0 === (workInProgress.mode & 1) && (primaryChildren.lanes = renderLanes); + 0 === (workInProgress.mode & 2) && (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)); + ((current.nextEffect = null), + (current.flags = 8), + (workInProgress.firstEffect = workInProgress.lastEffect = current)); return (workInProgress.child = primaryChildren); } function updateSuspenseFallbackChildren( @@ -4753,27 +4652,33 @@ function updateSuspenseFallbackChildren( fallbackChildren, renderLanes ) { - var mode = workInProgress.mode; - current = current.child; - var currentFallbackChildFragment = current.sibling, - primaryChildProps = { mode: "hidden", children: primaryChildren }; - 0 === (mode & 1) && workInProgress.child !== current + var mode = workInProgress.mode, + currentPrimaryChildFragment = current.child; + current = currentPrimaryChildFragment.sibling; + var primaryChildProps = { mode: "hidden", children: primaryChildren }; + 0 === (mode & 2) && workInProgress.child !== currentPrimaryChildFragment ? ((primaryChildren = workInProgress.child), (primaryChildren.childLanes = 0), (primaryChildren.pendingProps = primaryChildProps), - workInProgress.mode & 4 && + workInProgress.mode & 8 && ((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 & 131072)); - null !== currentFallbackChildFragment - ? (fallbackChildren = createWorkInProgress( - currentFallbackChildFragment, - fallbackChildren - )) + (primaryChildren.selfBaseDuration = + currentPrimaryChildFragment.selfBaseDuration), + (primaryChildren.treeBaseDuration = + currentPrimaryChildFragment.treeBaseDuration)), + (currentPrimaryChildFragment = primaryChildren.lastEffect), + null !== currentPrimaryChildFragment + ? ((workInProgress.firstEffect = primaryChildren.firstEffect), + (workInProgress.lastEffect = currentPrimaryChildFragment), + (currentPrimaryChildFragment.nextEffect = null)) + : (workInProgress.firstEffect = workInProgress.lastEffect = null)) + : (primaryChildren = createWorkInProgress( + currentPrimaryChildFragment, + primaryChildProps + )); + null !== current + ? (fallbackChildren = createWorkInProgress(current, fallbackChildren)) : ((fallbackChildren = createFiberFromFragment( fallbackChildren, mode, @@ -4798,7 +4703,8 @@ function initSuspenseListRenderState( isBackwards, tail, lastContentRow, - tailMode + tailMode, + lastEffectBeforeRendering ) { var renderState = workInProgress.memoizedState; null === renderState @@ -4808,14 +4714,16 @@ function initSuspenseListRenderState( renderingStartTime: 0, last: lastContentRow, tail: tail, - tailMode: tailMode + tailMode: tailMode, + lastEffect: lastEffectBeforeRendering }) : ((renderState.isBackwards = isBackwards), (renderState.rendering = null), (renderState.renderingStartTime = 0), (renderState.last = lastContentRow), (renderState.tail = tail), - (renderState.tailMode = tailMode)); + (renderState.tailMode = tailMode), + (renderState.lastEffect = lastEffectBeforeRendering)); } function updateSuspenseListComponent(current, workInProgress, renderLanes) { var nextProps = workInProgress.pendingProps, @@ -4824,9 +4732,9 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { reconcileChildren(current, workInProgress, nextProps.children, renderLanes); nextProps = suspenseStackCursor.current; if (0 !== (nextProps & 2)) - (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 128); + (nextProps = (nextProps & 1) | 2), (workInProgress.flags |= 64); else { - if (null !== current && 0 !== (current.flags & 128)) + if (null !== current && 0 !== (current.flags & 64)) a: for (current = workInProgress.child; null !== current; ) { if (13 === current.tag) null !== current.memoizedState && @@ -4849,7 +4757,7 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { nextProps &= 1; } push(suspenseStackCursor, nextProps); - if (0 === (workInProgress.mode & 1)) workInProgress.memoizedState = null; + if (0 === (workInProgress.mode & 2)) workInProgress.memoizedState = null; else switch (revealOrder) { case "forwards": @@ -4870,7 +4778,8 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !1, revealOrder, renderLanes, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "backwards": @@ -4892,11 +4801,19 @@ function updateSuspenseListComponent(current, workInProgress, renderLanes) { !0, renderLanes, null, - tailMode + tailMode, + workInProgress.lastEffect ); break; case "together": - initSuspenseListRenderState(workInProgress, !1, null, null, void 0); + initSuspenseListRenderState( + workInProgress, + !1, + null, + null, + void 0, + workInProgress.lastEffect + ); break; default: workInProgress.memoizedState = null; @@ -4907,23 +4824,25 @@ 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; + if (0 !== (renderLanes & workInProgress.childLanes)) { + 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; } - return workInProgress.child; + return null; } var appendAllChildren, updateHostContainer, @@ -4970,76 +4889,16 @@ function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) { break; case "collapsed": lastTailNode = renderState.tail; - for (var lastTailNode$63 = null; null !== lastTailNode; ) - null !== lastTailNode.alternate && (lastTailNode$63 = lastTailNode), + for (var lastTailNode$65 = null; null !== lastTailNode; ) + null !== lastTailNode.alternate && (lastTailNode$65 = lastTailNode), (lastTailNode = lastTailNode.sibling); - null === lastTailNode$63 + null === lastTailNode$65 ? hasRenderedATailFallback || null === renderState.tail ? (renderState.tail = null) : (renderState.tail.sibling = null) - : (lastTailNode$63.sibling = null); + : (lastTailNode$65.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 & 4)) { - for ( - var treeBaseDuration$65 = completedWork.selfBaseDuration, - child$66 = completedWork.child; - null !== child$66; - - ) - (newChildLanes |= child$66.lanes | child$66.childLanes), - (subtreeFlags |= child$66.subtreeFlags & 131072), - (subtreeFlags |= child$66.flags & 131072), - (treeBaseDuration$65 += child$66.treeBaseDuration), - (child$66 = child$66.sibling); - completedWork.treeBaseDuration = treeBaseDuration$65; - } else - for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; - - ) - (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags & 131072), - (subtreeFlags |= treeBaseDuration$65.flags & 131072), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); - else if (0 !== (completedWork.mode & 4)) { - treeBaseDuration$65 = completedWork.actualDuration; - child$66 = completedWork.selfBaseDuration; - for (var child = completedWork.child; null !== child; ) - (newChildLanes |= child.lanes | child.childLanes), - (subtreeFlags |= child.subtreeFlags), - (subtreeFlags |= child.flags), - (treeBaseDuration$65 += child.actualDuration), - (child$66 += child.treeBaseDuration), - (child = child.sibling); - completedWork.actualDuration = treeBaseDuration$65; - completedWork.treeBaseDuration = child$66; - } else - for ( - treeBaseDuration$65 = completedWork.child; - null !== treeBaseDuration$65; - - ) - (newChildLanes |= - treeBaseDuration$65.lanes | treeBaseDuration$65.childLanes), - (subtreeFlags |= treeBaseDuration$65.subtreeFlags), - (subtreeFlags |= treeBaseDuration$65.flags), - (treeBaseDuration$65.return = completedWork), - (treeBaseDuration$65 = treeBaseDuration$65.sibling); - completedWork.subtreeFlags |= subtreeFlags; - completedWork.childLanes = newChildLanes; - return didBailout; -} function completeWork(current, workInProgress, renderLanes) { var newProps = workInProgress.pendingProps; switch (workInProgress.tag) { @@ -5053,80 +4912,76 @@ function completeWork(current, workInProgress, renderLanes) { case 12: case 9: case 14: - return bubbleProperties(workInProgress), null; + return null; case 1: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 3: return ( - (newProps = workInProgress.stateNode), popHostContainer(), pop(didPerformWorkStackCursor), pop(contextStackCursor), resetWorkInProgressVersions(), + (newProps = workInProgress.stateNode), newProps.pendingContext && ((newProps.context = newProps.pendingContext), (newProps.pendingContext = null)), (null !== current && null !== current.child) || newProps.hydrate || - (workInProgress.flags |= 512), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), + (workInProgress.flags |= 256), + updateHostContainer(workInProgress), null ); case 5: popHostContext(workInProgress); - renderLanes = requiredContext(rootInstanceStackCursor.current); - var type = workInProgress.type; + var rootContainerInstance = requiredContext( + rootInstanceStackCursor.current + ); + renderLanes = workInProgress.type; if (null !== current && null != workInProgress.stateNode) updateHostComponent$1( current, workInProgress, - type, + renderLanes, newProps, - renderLanes + rootContainerInstance ), - current.ref !== workInProgress.ref && (workInProgress.flags |= 256); + current.ref !== workInProgress.ref && (workInProgress.flags |= 128); 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); + renderLanes = getViewConfigForType(renderLanes); var updatePayload = diffProperties( null, emptyObject, newProps, - type.validAttributes + renderLanes.validAttributes ); ReactNativePrivateInterface.UIManager.createView( current, - type.uiViewClassName, - renderLanes, + renderLanes.uiViewClassName, + rootContainerInstance, updatePayload ); - renderLanes = new ReactNativeFiberHostComponent( + rootContainerInstance = new ReactNativeFiberHostComponent( current, - type, + renderLanes, 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); + appendAllChildren(rootContainerInstance, workInProgress, !1, !1); + workInProgress.stateNode = rootContainerInstance; + finalizeInitialChildren(rootContainerInstance) && + (workInProgress.flags |= 4); + null !== workInProgress.ref && (workInProgress.flags |= 128); } - bubbleProperties(workInProgress); return null; case 6: if (current && null != workInProgress.stateNode) @@ -5146,32 +5001,32 @@ function completeWork(current, workInProgress, renderLanes) { throw Error( "Text strings must be rendered within a component." ); - renderLanes = allocateTag(); + rootContainerInstance = allocateTag(); ReactNativePrivateInterface.UIManager.createView( - renderLanes, + rootContainerInstance, "RCTRawText", current, { text: newProps } ); - instanceCache.set(renderLanes, workInProgress); - workInProgress.stateNode = renderLanes; + instanceCache.set(rootContainerInstance, workInProgress); + workInProgress.stateNode = rootContainerInstance; } - bubbleProperties(workInProgress); return null; case 13: pop(suspenseStackCursor); newProps = workInProgress.memoizedState; - if (0 !== (workInProgress.flags & 128)) + if (0 !== (workInProgress.flags & 64)) return ( (workInProgress.lanes = renderLanes), - 0 !== (workInProgress.mode & 4) && + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress ); newProps = null !== newProps; - renderLanes = !1; - null !== current && (renderLanes = null !== current.memoizedState); - if (newProps && !renderLanes && 0 !== (workInProgress.mode & 1)) + rootContainerInstance = !1; + null !== current && + (rootContainerInstance = null !== current.memoizedState); + if (newProps && !rootContainerInstance && 0 !== (workInProgress.mode & 2)) if ( (null === current && !0 !== workInProgress.memoizedProps.unstable_avoidThisFallback) || @@ -5186,100 +5041,89 @@ function completeWork(current, workInProgress, renderLanes) { ) workInProgressRootExitStatus = 4; null === workInProgressRoot || - (0 === (workInProgressRootSkippedLanes & 268435455) && - 0 === (workInProgressRootUpdatedLanes & 268435455)) || + (0 === (workInProgressRootSkippedLanes & 134217727) && + 0 === (workInProgressRootUpdatedLanes & 134217727)) || markRootSuspended$1( workInProgressRoot, workInProgressRootRenderLanes ); } - if (newProps || renderLanes) workInProgress.flags |= 4; - bubbleProperties(workInProgress); - 0 !== (workInProgress.mode & 4) && - newProps && - ((current = workInProgress.child), - null !== current && - (workInProgress.treeBaseDuration -= current.treeBaseDuration)); + if (newProps || rootContainerInstance) workInProgress.flags |= 4; return null; case 4: - return ( - popHostContainer(), - updateHostContainer(current, workInProgress), - bubbleProperties(workInProgress), - null - ); + return popHostContainer(), updateHostContainer(workInProgress), null; case 10: - return ( - popProvider(workInProgress.type._context), - bubbleProperties(workInProgress), - null - ); + return popProvider(workInProgress), null; case 17: - return ( - isContextProvider(workInProgress.type) && popContext(), - bubbleProperties(workInProgress), - null - ); + return isContextProvider(workInProgress.type) && popContext(), null; case 19: pop(suspenseStackCursor); - type = workInProgress.memoizedState; - if (null === type) return bubbleProperties(workInProgress), null; - newProps = 0 !== (workInProgress.flags & 128); - updatePayload = type.rendering; + newProps = workInProgress.memoizedState; + if (null === newProps) return null; + rootContainerInstance = 0 !== (workInProgress.flags & 64); + updatePayload = newProps.rendering; if (null === updatePayload) - if (newProps) cutOffTailIfNeeded(type, !1); + if (rootContainerInstance) cutOffTailIfNeeded(newProps, !1); else { if ( 0 !== workInProgressRootExitStatus || - (null !== current && 0 !== (current.flags & 128)) + (null !== current && 0 !== (current.flags & 64)) ) for (current = workInProgress.child; null !== current; ) { updatePayload = findFirstSuspended(current); if (null !== updatePayload) { - workInProgress.flags |= 128; - cutOffTailIfNeeded(type, !1); + workInProgress.flags |= 64; + cutOffTailIfNeeded(newProps, !1); current = updatePayload.updateQueue; null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)); - workInProgress.subtreeFlags = 0; + null === newProps.lastEffect && + (workInProgress.firstEffect = null); + workInProgress.lastEffect = newProps.lastEffect; current = renderLanes; for (newProps = workInProgress.child; null !== newProps; ) - (renderLanes = newProps), + (rootContainerInstance = newProps), (updatePayload = current), - (renderLanes.flags &= 131074), - (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 = type.subtreeFlags), - (renderLanes.deletions = null), - (renderLanes.memoizedProps = type.memoizedProps), - (renderLanes.memoizedState = type.memoizedState), - (renderLanes.updateQueue = type.updateQueue), - (renderLanes.type = type.type), - (updatePayload = type.dependencies), - (renderLanes.dependencies = + (rootContainerInstance.flags &= 2), + (rootContainerInstance.nextEffect = null), + (rootContainerInstance.firstEffect = null), + (rootContainerInstance.lastEffect = null), + (renderLanes = rootContainerInstance.alternate), + null === renderLanes + ? ((rootContainerInstance.childLanes = 0), + (rootContainerInstance.lanes = updatePayload), + (rootContainerInstance.child = null), + (rootContainerInstance.memoizedProps = null), + (rootContainerInstance.memoizedState = null), + (rootContainerInstance.updateQueue = null), + (rootContainerInstance.dependencies = null), + (rootContainerInstance.stateNode = null), + (rootContainerInstance.selfBaseDuration = 0), + (rootContainerInstance.treeBaseDuration = 0)) + : ((rootContainerInstance.childLanes = + renderLanes.childLanes), + (rootContainerInstance.lanes = renderLanes.lanes), + (rootContainerInstance.child = renderLanes.child), + (rootContainerInstance.memoizedProps = + renderLanes.memoizedProps), + (rootContainerInstance.memoizedState = + renderLanes.memoizedState), + (rootContainerInstance.updateQueue = + renderLanes.updateQueue), + (rootContainerInstance.type = renderLanes.type), + (updatePayload = renderLanes.dependencies), + (rootContainerInstance.dependencies = null === updatePayload ? null : { lanes: updatePayload.lanes, firstContext: updatePayload.firstContext }), - (renderLanes.selfBaseDuration = type.selfBaseDuration), - (renderLanes.treeBaseDuration = type.treeBaseDuration)), + (rootContainerInstance.selfBaseDuration = + renderLanes.selfBaseDuration), + (rootContainerInstance.treeBaseDuration = + renderLanes.treeBaseDuration)), (newProps = newProps.sibling); push( suspenseStackCursor, @@ -5289,76 +5133,80 @@ function completeWork(current, workInProgress, renderLanes) { } current = current.sibling; } - null !== type.tail && + null !== newProps.tail && now() > workInProgressRootRenderTargetTime && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608)); + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432)); } else { - if (!newProps) + if (!rootContainerInstance) if ( ((current = findFirstSuspended(updatePayload)), null !== current) ) { if ( - ((workInProgress.flags |= 128), - (newProps = !0), + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), (current = current.updateQueue), null !== current && ((workInProgress.updateQueue = current), (workInProgress.flags |= 4)), - cutOffTailIfNeeded(type, !0), - null === type.tail && - "hidden" === type.tailMode && + cutOffTailIfNeeded(newProps, !0), + null === newProps.tail && + "hidden" === newProps.tailMode && !updatePayload.alternate) ) - return bubbleProperties(workInProgress), null; + return ( + (workInProgress = workInProgress.lastEffect = + newProps.lastEffect), + null !== workInProgress && (workInProgress.nextEffect = null), + null + ); } else - 2 * now() - type.renderingStartTime > + 2 * now() - newProps.renderingStartTime > workInProgressRootRenderTargetTime && 1073741824 !== renderLanes && - ((workInProgress.flags |= 128), - (newProps = !0), - cutOffTailIfNeeded(type, !1), - (workInProgress.lanes = 8388608), - markSpawnedWork(8388608)); - type.isBackwards + ((workInProgress.flags |= 64), + (rootContainerInstance = !0), + cutOffTailIfNeeded(newProps, !1), + (workInProgress.lanes = 33554432), + markSpawnedWork(33554432)); + newProps.isBackwards ? ((updatePayload.sibling = workInProgress.child), (workInProgress.child = updatePayload)) - : ((current = type.last), + : ((current = newProps.last), null !== current ? (current.sibling = updatePayload) : (workInProgress.child = updatePayload), - (type.last = updatePayload)); + (newProps.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; + return null !== newProps.tail + ? ((current = newProps.tail), + (newProps.rendering = current), + (newProps.tail = current.sibling), + (newProps.lastEffect = workInProgress.lastEffect), + (newProps.renderingStartTime = now()), + (current.sibling = null), + (workInProgress = suspenseStackCursor.current), + push( + suspenseStackCursor, + rootContainerInstance + ? (workInProgress & 1) | 2 + : workInProgress & 1 + ), + current) + : null; case 22: case 23: return ( popRenderLanes(), - (renderLanes = null !== workInProgress.memoizedState), null !== current && - (null !== current.memoizedState) !== renderLanes && + (null !== current.memoizedState) !== + (null !== workInProgress.memoizedState) && "unstable-defer-without-hiding" !== newProps.mode && (workInProgress.flags |= 4), - (renderLanes && - 0 === (subtreeRenderLanes & 1073741824) && - 0 !== (workInProgress.mode & 2)) || - bubbleProperties(workInProgress), null ); } @@ -5373,9 +5221,9 @@ function unwindWork(workInProgress) { case 1: isContextProvider(workInProgress.type) && popContext(); var flags = workInProgress.flags; - return flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), - 0 !== (workInProgress.mode & 4) && + return flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress) : null; @@ -5385,11 +5233,11 @@ function unwindWork(workInProgress) { pop(contextStackCursor); resetWorkInProgressVersions(); flags = workInProgress.flags; - if (0 !== (flags & 128)) + if (0 !== (flags & 64)) throw Error( "The root failed to unmount after an error. This is likely a bug in React. Please file an issue." ); - workInProgress.flags = (flags & -16385) | 128; + workInProgress.flags = (flags & -8193) | 64; return workInProgress; case 5: return popHostContext(workInProgress), null; @@ -5397,9 +5245,9 @@ function unwindWork(workInProgress) { return ( pop(suspenseStackCursor), (flags = workInProgress.flags), - flags & 16384 - ? ((workInProgress.flags = (flags & -16385) | 128), - 0 !== (workInProgress.mode & 4) && + flags & 8192 + ? ((workInProgress.flags = (flags & -8193) | 64), + 0 !== (workInProgress.mode & 8) && transferActualDuration(workInProgress), workInProgress) : null @@ -5409,12 +5257,10 @@ function unwindWork(workInProgress) { case 4: return popHostContainer(), null; case 10: - return popProvider(workInProgress.type._context), null; + return popProvider(workInProgress), null; case 22: case 23: return popRenderLanes(), null; - case 24: - return null; default: return null; } @@ -5487,150 +5333,152 @@ function createClassErrorUpdate(fiber, errorInfo, lane) { }); return lane; } -var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set, - nextEffect = null; -function safelyDetachRef(current, nearestMountedAncestor) { +var PossiblyWeakSet = "function" === typeof WeakSet ? WeakSet : Set; +function safelyDetachRef(current) { var ref = current.ref; if (null !== ref) if ("function" === typeof ref) try { ref(null); } catch (refError) { - captureCommitPhaseError(current, nearestMountedAncestor, refError); + captureCommitPhaseError(current, refError); } else ref.current = null; } -var focusedInstanceHandle = null, - shouldFireAfterActiveInstanceBlur = !1; -function commitBeforeMutationEffects(root, firstChild) { - focusedInstanceHandle = null; - for (nextEffect = firstChild; null !== nextEffect; ) { - root = nextEffect; - firstChild = root.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) - doesFiberContain(firstChild[i], focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - firstChild = root.child; - if (0 !== (root.subtreeFlags & 516) && null !== firstChild) - (firstChild.return = root), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - root = nextEffect; - try { - var current = root.alternate, - flags = root.flags; - if ( - !shouldFireAfterActiveInstanceBlur && - null !== focusedInstanceHandle - ) { - var JSCompiler_temp; - if ((JSCompiler_temp = 13 === root.tag)) - a: { - if (null !== current) { - var oldState = current.memoizedState; - if (null === oldState || null !== oldState.dehydrated) { - var newState = root.memoizedState; - JSCompiler_temp = - null !== newState && null === newState.dehydrated; - break a; - } - } - JSCompiler_temp = !1; - } - JSCompiler_temp && - doesFiberContain(root, focusedInstanceHandle) && - (shouldFireAfterActiveInstanceBlur = !0); - } - if (0 !== (flags & 512)) - switch (root.tag) { - case 0: - case 11: - case 15: - break; - case 1: - if (null !== current) { - var prevProps = current.memoizedProps, - prevState = current.memoizedState, - instance = root.stateNode, - snapshot = instance.getSnapshotBeforeUpdate( - root.elementType === root.type - ? prevProps - : resolveDefaultProps(root.type, prevProps), - prevState - ); - instance.__reactInternalSnapshotBeforeUpdate = snapshot; - } - break; - case 3: - break; - case 5: - case 6: - case 4: - case 17: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - } catch (error) { - captureCommitPhaseError(root, root.return, error); - } - firstChild = root.sibling; - if (null !== firstChild) { - firstChild.return = root.return; - nextEffect = firstChild; - break; - } - nextEffect = root.return; +function commitBeforeMutationLifeCycles(current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + return; + case 1: + if (finishedWork.flags & 256 && null !== current) { + var prevProps = current.memoizedProps, + prevState = current.memoizedState; + current = finishedWork.stateNode; + finishedWork = current.getSnapshotBeforeUpdate( + finishedWork.elementType === finishedWork.type + ? prevProps + : resolveDefaultProps(finishedWork.type, prevProps), + prevState + ); + current.__reactInternalSnapshotBeforeUpdate = finishedWork; } + return; + case 3: + return; + case 5: + case 6: + case 4: + case 17: + return; } - current = shouldFireAfterActiveInstanceBlur; - shouldFireAfterActiveInstanceBlur = !1; - focusedInstanceHandle = null; - return current; + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } -function commitHookEffectListUnmount( - flags, - finishedWork, - nearestMountedAncestor$jscomp$0 -) { - var updateQueue = finishedWork.updateQueue; - updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; - if (null !== updateQueue) { - var effect = (updateQueue = updateQueue.next); - do { - if ((effect.tag & flags) === flags) { - var destroy = effect.destroy; - effect.destroy = void 0; - if (void 0 !== destroy) { - var current = finishedWork, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(current, nearestMountedAncestor, error); +function commitLifeCycles(finishedRoot, current, finishedWork) { + switch (finishedWork.tag) { + case 0: + case 11: + case 15: + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + if (3 === (finishedRoot.tag & 3)) { + var create$82 = finishedRoot.create; + finishedRoot.destroy = create$82(); } - } + finishedRoot = finishedRoot.next; + } while (finishedRoot !== current); } - effect = effect.next; - } while (effect !== updateQueue); - } -} -function commitHookEffectListMount(tag, finishedWork) { - finishedWork = finishedWork.updateQueue; - finishedWork = null !== finishedWork ? finishedWork.lastEffect : null; - if (null !== finishedWork) { - var effect = (finishedWork = finishedWork.next); - do { - if ((effect.tag & tag) === tag) { - var create$84 = effect.create; - effect.destroy = create$84(); + current = finishedWork.updateQueue; + current = null !== current ? current.lastEffect : null; + if (null !== current) { + finishedRoot = current = current.next; + do { + var _effect = finishedRoot; + create$82 = _effect.next; + _effect = _effect.tag; + 0 !== (_effect & 4) && + 0 !== (_effect & 1) && + (enqueuePendingPassiveHookEffectUnmount(finishedWork, finishedRoot), + enqueuePendingPassiveHookEffectMount(finishedWork, finishedRoot)); + finishedRoot = create$82; + } while (finishedRoot !== current); + } + return; + case 1: + finishedRoot = finishedWork.stateNode; + finishedWork.flags & 4 && + (null === current + ? finishedRoot.componentDidMount() + : ((create$82 = + finishedWork.elementType === finishedWork.type + ? current.memoizedProps + : resolveDefaultProps( + finishedWork.type, + current.memoizedProps + )), + finishedRoot.componentDidUpdate( + create$82, + current.memoizedState, + finishedRoot.__reactInternalSnapshotBeforeUpdate + ))); + current = finishedWork.updateQueue; + null !== current && + commitUpdateQueue(finishedWork, current, finishedRoot); + return; + case 3: + current = finishedWork.updateQueue; + if (null !== current) { + finishedRoot = null; + if (null !== finishedWork.child) + switch (finishedWork.child.tag) { + case 5: + finishedRoot = finishedWork.child.stateNode; + break; + case 1: + finishedRoot = finishedWork.child.stateNode; + } + commitUpdateQueue(finishedWork, current, finishedRoot); } - effect = effect.next; - } while (effect !== finishedWork); + return; + case 5: + return; + case 6: + return; + case 4: + return; + case 12: + create$82 = finishedWork.memoizedProps.onRender; + _effect = commitTime; + "function" === typeof create$82 && + create$82( + finishedWork.memoizedProps.id, + null === current ? "mount" : "update", + finishedWork.actualDuration, + finishedWork.treeBaseDuration, + finishedWork.actualStartTime, + _effect, + finishedRoot.memoizedInteractions + ); + return; + case 13: + return; + case 19: + case 17: + case 20: + case 21: + case 22: + case 23: + return; } + throw Error( + "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." + ); } function hideOrUnhideAllChildren(finishedWork, isHidden) { for (var node = finishedWork; ; ) { @@ -5690,7 +5538,7 @@ function hideOrUnhideAllChildren(finishedWork, isHidden) { node = node.sibling; } } -function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { +function commitUnmount(finishedRoot, current) { if (injectedHook && "function" === typeof injectedHook.onCommitFiberUnmount) try { injectedHook.onCommitFiberUnmount(rendererID, current); @@ -5707,24 +5555,26 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { ) { var effect = (finishedRoot = finishedRoot.next); do { - var _effect = effect, - destroy = _effect.destroy; - _effect = _effect.tag; - if (void 0 !== destroy && 0 !== (_effect & 2)) { - _effect = current; - var nearestMountedAncestor = nearestMountedAncestor$jscomp$0; - try { - destroy(); - } catch (error) { - captureCommitPhaseError(_effect, nearestMountedAncestor, error); + var _effect2 = effect, + destroy = _effect2.destroy; + _effect2 = _effect2.tag; + if (void 0 !== destroy) + if (0 !== (_effect2 & 4)) + enqueuePendingPassiveHookEffectUnmount(current, effect); + else { + _effect2 = current; + try { + destroy(); + } catch (error) { + captureCommitPhaseError(_effect2, error); + } } - } effect = effect.next; } while (effect !== finishedRoot); } break; case 1: - safelyDetachRef(current, nearestMountedAncestor$jscomp$0); + safelyDetachRef(current); finishedRoot = current.stateNode; if ("function" === typeof finishedRoot.componentWillUnmount) try { @@ -5732,34 +5582,26 @@ function commitUnmount(finishedRoot, current, nearestMountedAncestor$jscomp$0) { (finishedRoot.state = current.memoizedState), finishedRoot.componentWillUnmount(); } catch (unmountError) { - captureCommitPhaseError( - current, - nearestMountedAncestor$jscomp$0, - unmountError - ); + captureCommitPhaseError(current, unmountError); } break; case 5: - safelyDetachRef(current, nearestMountedAncestor$jscomp$0); + safelyDetachRef(current); break; case 4: - unmountHostComponents( - finishedRoot, - current, - nearestMountedAncestor$jscomp$0 - ); + unmountHostComponents(finishedRoot, current); } } -function detachFiberAfterEffects(fiber) { +function detachFiberMutation(fiber) { fiber.alternate = null; fiber.child = null; - fiber.deletions = null; fiber.dependencies = null; + fiber.firstEffect = null; + fiber.lastEffect = null; fiber.memoizedProps = null; fiber.memoizedState = null; fiber.pendingProps = null; - fiber.sibling = null; - fiber.stateNode = null; + fiber.return = null; fiber.updateQueue = null; } function isHostParent(fiber) { @@ -5794,7 +5636,7 @@ function commitPlacement(finishedWork) { "Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue." ); } - parentFiber.flags & 32 && (parentFiber.flags &= -33); + parentFiber.flags & 16 && (parentFiber.flags &= -17); a: b: for (parentFiber = finishedWork; ; ) { for (; null === parentFiber.sibling; ) { if (null === parentFiber.return || isHostParent(parentFiber.return)) { @@ -5910,11 +5752,7 @@ function insertOrAppendPlacementNode(node, before, parent) { ) insertOrAppendPlacementNode(node, before, parent), (node = node.sibling); } -function unmountHostComponents( - finishedRoot$jscomp$0, - current, - nearestMountedAncestor$jscomp$0 -) { +function unmountHostComponents(finishedRoot$jscomp$0, current) { for ( var node = current, currentParentIsValid = !1, @@ -5952,13 +5790,12 @@ function unmountHostComponents( a: for ( var finishedRoot = finishedRoot$jscomp$0, root = node, - nearestMountedAncestor = nearestMountedAncestor$jscomp$0, node$jscomp$0 = root; ; ) if ( - (commitUnmount(finishedRoot, node$jscomp$0, nearestMountedAncestor), + (commitUnmount(finishedRoot, node$jscomp$0), null !== node$jscomp$0.child && 4 !== node$jscomp$0.tag) ) (node$jscomp$0.child.return = node$jscomp$0), @@ -5985,18 +5822,18 @@ function unmountHostComponents( [0] )) : ((finishedRoot = currentParent), - (nearestMountedAncestor = node.stateNode), - recursivelyUncacheFiberNode(nearestMountedAncestor), + (node$jscomp$0 = node.stateNode), + recursivelyUncacheFiberNode(node$jscomp$0), (root = finishedRoot._children), - (nearestMountedAncestor = root.indexOf(nearestMountedAncestor)), - root.splice(nearestMountedAncestor, 1), + (node$jscomp$0 = root.indexOf(node$jscomp$0)), + root.splice(node$jscomp$0, 1), ReactNativePrivateInterface.UIManager.manageChildren( finishedRoot._nativeTag, [], [], [], [], - [nearestMountedAncestor] + [node$jscomp$0] )); } else if (4 === node.tag) { if (null !== node.child) { @@ -6007,12 +5844,7 @@ function unmountHostComponents( continue; } } else if ( - (commitUnmount( - finishedRoot$jscomp$0, - node, - nearestMountedAncestor$jscomp$0 - ), - null !== node.child) + (commitUnmount(finishedRoot$jscomp$0, node), null !== node.child) ) { node.child.return = node; node = node.child; @@ -6034,31 +5866,42 @@ function commitWork(current, finishedWork) { case 11: case 14: case 15: - commitHookEffectListUnmount(3, finishedWork, finishedWork.return); + var updateQueue = finishedWork.updateQueue; + updateQueue = null !== updateQueue ? updateQueue.lastEffect : null; + if (null !== updateQueue) { + var effect = (updateQueue = updateQueue.next); + do + 3 === (effect.tag & 3) && + ((finishedWork = effect.destroy), + (effect.destroy = void 0), + void 0 !== finishedWork && finishedWork()), + (effect = effect.next); + while (effect !== updateQueue); + } return; case 1: return; case 5: - var instance = finishedWork.stateNode; - if (null != instance) { - var newProps = finishedWork.memoizedProps; - current = null !== current ? current.memoizedProps : newProps; + updateQueue = finishedWork.stateNode; + if (null != updateQueue) { + effect = finishedWork.memoizedProps; + current = null !== current ? current.memoizedProps : effect; var updatePayload = finishedWork.updateQueue; finishedWork.updateQueue = null; null !== updatePayload && - ((finishedWork = instance.viewConfig), - instanceProps.set(instance._nativeTag, newProps), - (newProps = diffProperties( + ((finishedWork = updateQueue.viewConfig), + instanceProps.set(updateQueue._nativeTag, effect), + (effect = diffProperties( null, current, - newProps, + effect, finishedWork.validAttributes )), - null != newProps && + null != effect && ReactNativePrivateInterface.UIManager.updateView( - instance._nativeTag, + updateQueue._nativeTag, finishedWork.uiViewClassName, - newProps + effect )); } return; @@ -6100,228 +5943,31 @@ function commitWork(current, finishedWork) { "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." ); } -function attachSuspenseRetryListeners(finishedWork) { - var wakeables = finishedWork.updateQueue; - if (null !== wakeables) { - finishedWork.updateQueue = null; - var retryCache = finishedWork.stateNode; - null === retryCache && - (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); - wakeables.forEach(function(wakeable) { - var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); - retryCache.has(wakeable) || - (!0 !== wakeable.__reactDoNotTraceInteractions && - (retry = tracing.unstable_wrap(retry)), - retryCache.add(wakeable), - wakeable.then(retry, retry)); - }); - } -} -function commitMutationEffects(root, renderPriorityLevel, firstChild) { - for (nextEffect = firstChild; null !== nextEffect; ) { - renderPriorityLevel = nextEffect; - firstChild = renderPriorityLevel.deletions; - if (null !== firstChild) - for (var i = 0; i < firstChild.length; i++) { - var childToDelete = firstChild[i]; - try { - unmountHostComponents(root, childToDelete, renderPriorityLevel); - var alternate = childToDelete.alternate; - childToDelete.return = null; - null !== alternate && (alternate.return = null); - } catch (error) { - captureCommitPhaseError(childToDelete, renderPriorityLevel, error); - } - } - firstChild = renderPriorityLevel.child; - if (0 !== (renderPriorityLevel.subtreeFlags & 6454) && null !== firstChild) - (firstChild.return = renderPriorityLevel), (nextEffect = firstChild); - else - for (; null !== nextEffect; ) { - renderPriorityLevel = nextEffect; - try { - var flags = renderPriorityLevel.flags; - if (flags & 256) { - var current = renderPriorityLevel.alternate; - if (null !== current) { - var currentRef = current.ref; - null !== currentRef && - ("function" === typeof currentRef - ? currentRef(null) - : (currentRef.current = null)); - } - } - switch (flags & 2054) { - case 2: - commitPlacement(renderPriorityLevel); - renderPriorityLevel.flags &= -3; - break; - case 6: - commitPlacement(renderPriorityLevel); - renderPriorityLevel.flags &= -3; - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - break; - case 2048: - renderPriorityLevel.flags &= -2049; - break; - case 2052: - renderPriorityLevel.flags &= -2049; - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - break; - case 4: - commitWork(renderPriorityLevel.alternate, renderPriorityLevel); - } - } catch (error) { - captureCommitPhaseError( - renderPriorityLevel, - renderPriorityLevel.return, - error - ); - } - firstChild = renderPriorityLevel.sibling; - if (null !== firstChild) { - firstChild.return = renderPriorityLevel.return; - nextEffect = firstChild; - break; - } - nextEffect = renderPriorityLevel.return; - } - } -} -function commitLayoutEffects(finishedWork, root) { - for (nextEffect = finishedWork; null !== nextEffect; ) { - var fiber = nextEffect, - firstChild = fiber.child; - if (0 !== (fiber.subtreeFlags & 324) && null !== firstChild) - (firstChild.return = fiber), (nextEffect = firstChild); - else - for (fiber = finishedWork, firstChild = root; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - if (0 !== (fiber$jscomp$0.flags & 324)) { - var current = fiber$jscomp$0.alternate; - try { - var finishedRoot = firstChild; - if (0 !== (fiber$jscomp$0.flags & 68)) - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(3, fiber$jscomp$0); - break; - case 1: - var instance = fiber$jscomp$0.stateNode; - if (fiber$jscomp$0.flags & 4) - if (null === current) instance.componentDidMount(); - else { - var prevProps = - fiber$jscomp$0.elementType === fiber$jscomp$0.type - ? current.memoizedProps - : resolveDefaultProps( - fiber$jscomp$0.type, - current.memoizedProps - ); - instance.componentDidUpdate( - prevProps, - current.memoizedState, - instance.__reactInternalSnapshotBeforeUpdate - ); - } - var updateQueue = fiber$jscomp$0.updateQueue; - null !== updateQueue && - commitUpdateQueue(fiber$jscomp$0, updateQueue, instance); - break; - case 3: - var updateQueue$85 = fiber$jscomp$0.updateQueue; - if (null !== updateQueue$85) { - finishedRoot = null; - if (null !== fiber$jscomp$0.child) - switch (fiber$jscomp$0.child.tag) { - case 5: - finishedRoot = fiber$jscomp$0.child.stateNode; - break; - case 1: - finishedRoot = fiber$jscomp$0.child.stateNode; - } - commitUpdateQueue( - fiber$jscomp$0, - updateQueue$85, - finishedRoot - ); - } - break; - case 5: - break; - case 6: - break; - case 4: - break; - case 12: - var onRender = fiber$jscomp$0.memoizedProps.onRender, - commitTime$88 = commitTime; - current = null === current ? "mount" : "update"; - "function" === typeof onRender && - onRender( - fiber$jscomp$0.memoizedProps.id, - current, - fiber$jscomp$0.actualDuration, - fiber$jscomp$0.treeBaseDuration, - fiber$jscomp$0.actualStartTime, - commitTime$88, - finishedRoot.memoizedInteractions - ); - break; - case 13: - break; - case 19: - case 17: - case 21: - case 22: - case 23: - break; - default: - throw Error( - "This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue." - ); - } - if (fiber$jscomp$0.flags & 256) { - finishedRoot = void 0; - var ref = fiber$jscomp$0.ref; - if (null !== ref) { - var instance$jscomp$0 = fiber$jscomp$0.stateNode; - switch (fiber$jscomp$0.tag) { - case 5: - finishedRoot = instance$jscomp$0; - break; - default: - finishedRoot = instance$jscomp$0; - } - "function" === typeof ref - ? ref(finishedRoot) - : (ref.current = finishedRoot); - } - } - } catch (error) { - captureCommitPhaseError( - fiber$jscomp$0, - fiber$jscomp$0.return, - error - ); - } - } - if (fiber$jscomp$0 === fiber) { - nextEffect = null; - break; - } - finishedRoot = fiber$jscomp$0.sibling; - if (null !== finishedRoot) { - finishedRoot.return = fiber$jscomp$0.return; - nextEffect = finishedRoot; - break; - } - nextEffect = fiber$jscomp$0.return; - } +function attachSuspenseRetryListeners(finishedWork) { + var wakeables = finishedWork.updateQueue; + if (null !== wakeables) { + finishedWork.updateQueue = null; + var retryCache = finishedWork.stateNode; + null === retryCache && + (retryCache = finishedWork.stateNode = new PossiblyWeakSet()); + wakeables.forEach(function(wakeable) { + var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable); + retryCache.has(wakeable) || + (!0 !== wakeable.__reactDoNotTraceInteractions && + (retry = tracing.unstable_wrap(retry)), + retryCache.add(wakeable), + wakeable.then(retry, retry)); + }); } } +function isSuspenseBoundaryBeingHidden(current, finishedWork) { + return null !== current && + ((current = current.memoizedState), + null === current || null !== current.dehydrated) + ? ((finishedWork = finishedWork.memoizedState), + null !== finishedWork && null === finishedWork.dehydrated) + : !1; +} var ceil = Math.ceil, ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher, ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner, @@ -6333,11 +5979,14 @@ var ceil = Math.ceil, subtreeRenderLanesCursor = createCursor(0), workInProgressRootExitStatus = 0, workInProgressRootFatalError = null, + workInProgressRootIncludedLanes = 0, workInProgressRootSkippedLanes = 0, workInProgressRootUpdatedLanes = 0, workInProgressRootPingedLanes = 0, + mostRecentlyUpdatedRoot = null, globalMostRecentFallbackTime = 0, workInProgressRootRenderTargetTime = Infinity, + nextEffect = null, hasUncaughtError = !1, firstUncaughtError = null, legacyErrorBoundariesThatAlreadyFailed = null, @@ -6345,12 +5994,17 @@ var ceil = Math.ceil, rootWithPendingPassiveEffects = null, pendingPassiveEffectsRenderPriority = 90, pendingPassiveEffectsLanes = 0, + pendingPassiveHookEffectsMount = [], + pendingPassiveHookEffectsUnmount = [], rootsWithPendingDiscreteUpdates = null, nestedUpdateCount = 0, rootWithNestedUpdates = null, spawnedWorkDuringRender = null, currentEventTime = -1, - currentEventTransitionLane = 0; + currentEventWipLanes = 0, + currentEventPendingLanes = 0, + focusedInstanceHandle = null, + shouldFireAfterActiveInstanceBlur = !1; function requestEventTime() { return 0 !== (executionContext & 48) ? now() @@ -6360,22 +6014,30 @@ function requestEventTime() { } function requestUpdateLane(fiber) { fiber = fiber.mode; - if (0 === (fiber & 1)) return 1; - if (0 === (fiber & 2)) return 99 === getCurrentPriorityLevel() ? 1 : 2; - if (0 !== ReactCurrentBatchConfig.transition) - return ( - 0 === currentEventTransitionLane && - ((fiber = nextTransitionLane), - (nextTransitionLane <<= 1), - 0 === (nextTransitionLane & 8388096) && (nextTransitionLane = 512), - (currentEventTransitionLane = fiber)), - currentEventTransitionLane - ); + if (0 === (fiber & 2)) return 1; + if (0 === (fiber & 4)) return 99 === getCurrentPriorityLevel() ? 1 : 2; + 0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes); + if (0 !== ReactCurrentBatchConfig.transition) { + 0 !== currentEventPendingLanes && + (currentEventPendingLanes = + null !== mostRecentlyUpdatedRoot + ? mostRecentlyUpdatedRoot.pendingLanes + : 0); + fiber = currentEventWipLanes; + var lane = 4186112 & ~currentEventPendingLanes; + lane &= -lane; + 0 === lane && + ((fiber = 4186112 & ~fiber), + (lane = fiber & -fiber), + 0 === lane && (lane = 8192)); + return lane; + } fiber = getCurrentPriorityLevel(); 0 !== (executionContext & 4) && 98 === fiber - ? (fiber = findUpdateLane(12)) + ? (fiber = findUpdateLane(12, currentEventWipLanes)) : ((fiber = schedulerPriorityToLanePriority(fiber)), - (fiber = findUpdateLane(fiber))); + (fiber = findUpdateLane(fiber, currentEventWipLanes))); return fiber; } function scheduleUpdateOnFiber(fiber, lane, eventTime) { @@ -6408,7 +6070,7 @@ function scheduleUpdateOnFiber(fiber, lane, eventTime) { : rootsWithPendingDiscreteUpdates.add(fiber)), ensureRootIsScheduled(fiber, eventTime), schedulePendingInteractions(fiber, lane)); - return fiber; + mostRecentlyUpdatedRoot = fiber; } function markUpdateLaneFromFiberToRoot(sourceFiber, lane) { sourceFiber.lanes |= lane; @@ -6433,15 +6095,15 @@ function ensureRootIsScheduled(root, currentTime) { 0 < lanes; ) { - var index$6 = 31 - clz32(lanes), - lane = 1 << index$6, - expirationTime = expirationTimes[index$6]; + var index$7 = 31 - clz32(lanes), + lane = 1 << index$7, + expirationTime = expirationTimes[index$7]; if (-1 === expirationTime) { if (0 === (lane & suspendedLanes) || 0 !== (lane & pingedLanes)) { expirationTime = currentTime; getHighestPriorityLanes(lane); var priority = return_highestLanePriority; - expirationTimes[index$6] = + expirationTimes[index$7] = 10 <= priority ? expirationTime + 250 : 6 <= priority @@ -6456,42 +6118,45 @@ function ensureRootIsScheduled(root, currentTime) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); currentTime = return_highestLanePriority; - 0 === suspendedLanes - ? (null !== existingCallbackNode && + if (0 === suspendedLanes) + null !== existingCallbackNode && + (existingCallbackNode !== fakeCallbackNode && Scheduler_cancelCallback(existingCallbackNode), (root.callbackNode = null), - (root.callbackPriority = 0)) - : root.callbackPriority !== currentTime && - (null != existingCallbackNode && - Scheduler_cancelCallback(existingCallbackNode), - 15 === currentTime - ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), - null === syncQueue - ? ((syncQueue = [existingCallbackNode]), - (immediateQueueCallbackNode = Scheduler_scheduleCallback( - Scheduler_ImmediatePriority, - flushSyncCallbackQueueImpl - ))) - : syncQueue.push(existingCallbackNode), - (existingCallbackNode = null)) - : 14 === currentTime - ? (existingCallbackNode = scheduleCallback( - 99, - performSyncWorkOnRoot.bind(null, root) - )) - : ((existingCallbackNode = lanePriorityToSchedulerPriority( - currentTime - )), - (existingCallbackNode = scheduleCallback( - existingCallbackNode, - performConcurrentWorkOnRoot.bind(null, root) - ))), - (root.callbackPriority = currentTime), - (root.callbackNode = existingCallbackNode)); -} -function performConcurrentWorkOnRoot(root, didTimeout) { + (root.callbackPriority = 0)); + else { + if (null !== existingCallbackNode) { + if (root.callbackPriority === currentTime) return; + existingCallbackNode !== fakeCallbackNode && + Scheduler_cancelCallback(existingCallbackNode); + } + 15 === currentTime + ? ((existingCallbackNode = performSyncWorkOnRoot.bind(null, root)), + null === syncQueue + ? ((syncQueue = [existingCallbackNode]), + (immediateQueueCallbackNode = Scheduler_scheduleCallback( + Scheduler_ImmediatePriority, + flushSyncCallbackQueueImpl + ))) + : syncQueue.push(existingCallbackNode), + (existingCallbackNode = fakeCallbackNode)) + : 14 === currentTime + ? (existingCallbackNode = scheduleCallback( + 99, + performSyncWorkOnRoot.bind(null, root) + )) + : ((existingCallbackNode = lanePriorityToSchedulerPriority(currentTime)), + (existingCallbackNode = scheduleCallback( + existingCallbackNode, + performConcurrentWorkOnRoot.bind(null, root) + ))); + root.callbackPriority = currentTime; + root.callbackNode = existingCallbackNode; + } +} +function performConcurrentWorkOnRoot(root) { currentEventTime = -1; - currentEventTransitionLane = 0; + currentEventPendingLanes = currentEventWipLanes = 0; if (0 !== (executionContext & 48)) throw Error("Should not already be working."); var originalCallbackNode = root.callbackNode; @@ -6502,14 +6167,8 @@ function performConcurrentWorkOnRoot(root, didTimeout) { root === workInProgressRoot ? workInProgressRootRenderLanes : 0 ); if (0 === lanes) return null; - if (didTimeout) - return ( - (root.expiredLanes |= lanes & root.pendingLanes), - ensureRootIsScheduled(root, now()), - null - ); var lanes$jscomp$0 = lanes; - didTimeout = executionContext; + var exitStatus = executionContext; executionContext |= 16; var prevDispatcher = pushDispatcher(); if ( @@ -6531,19 +6190,21 @@ function performConcurrentWorkOnRoot(root, didTimeout) { resetContextDependencies(); tracing.__interactionsRef.current = lanes$jscomp$0; ReactCurrentDispatcher$2.current = prevDispatcher; - executionContext = didTimeout; + executionContext = exitStatus; null !== workInProgress - ? (didTimeout = 0) + ? (exitStatus = 0) : ((workInProgressRoot = null), (workInProgressRootRenderLanes = 0), - (didTimeout = workInProgressRootExitStatus)); - if (0 !== didTimeout) { - 2 === didTimeout && + (exitStatus = workInProgressRootExitStatus)); + if (0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes)) + prepareFreshStack(root, 0); + else if (0 !== exitStatus) { + 2 === exitStatus && ((executionContext |= 64), root.hydrate && (root.hydrate = !1), (lanes = getLanesToRetrySynchronouslyOnError(root)), - 0 !== lanes && (didTimeout = renderRootSync(root, lanes))); - if (1 === didTimeout) + 0 !== lanes && (exitStatus = renderRootSync(root, lanes))); + if (1 === exitStatus) throw ((originalCallbackNode = workInProgressRootFatalError), prepareFreshStack(root, 0), markRootSuspended$1(root, lanes), @@ -6551,7 +6212,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { originalCallbackNode); root.finishedWork = root.current.alternate; root.finishedLanes = lanes; - switch (didTimeout) { + switch (exitStatus) { case 0: case 1: throw Error("Root did not complete. This is a bug in React."); @@ -6561,9 +6222,9 @@ function performConcurrentWorkOnRoot(root, didTimeout) { case 3: markRootSuspended$1(root, lanes); if ( - (lanes & 125829120) === lanes && - ((didTimeout = globalMostRecentFallbackTime + 500 - now()), - 10 < didTimeout) + (lanes & 62914560) === lanes && + ((exitStatus = globalMostRecentFallbackTime + 500 - now()), + 10 < exitStatus) ) { if (0 !== getNextLanes(root, 0)) break; prevDispatcher = root.suspendedLanes; @@ -6574,7 +6235,7 @@ function performConcurrentWorkOnRoot(root, didTimeout) { } root.timeoutHandle = scheduleTimeout( commitRoot.bind(null, root), - didTimeout + exitStatus ); break; } @@ -6582,13 +6243,13 @@ function performConcurrentWorkOnRoot(root, didTimeout) { break; case 4: markRootSuspended$1(root, lanes); - if ((lanes & 8388096) === lanes) break; - didTimeout = root.eventTimes; + if ((lanes & 4186112) === lanes) break; + exitStatus = root.eventTimes; for (prevDispatcher = -1; 0 < lanes; ) { - var index$5 = 31 - clz32(lanes); - lanes$jscomp$0 = 1 << index$5; - index$5 = didTimeout[index$5]; - index$5 > prevDispatcher && (prevDispatcher = index$5); + var index$6 = 31 - clz32(lanes); + lanes$jscomp$0 = 1 << index$6; + index$6 = exitStatus[index$6]; + index$6 > prevDispatcher && (prevDispatcher = index$6); lanes &= ~lanes$jscomp$0; } lanes = prevDispatcher; @@ -6634,9 +6295,9 @@ function markRootSuspended$1(root, suspendedLanes) { root.suspendedLanes |= suspendedLanes; root.pingedLanes &= ~suspendedLanes; for (root = root.expirationTimes; 0 < suspendedLanes; ) { - var index$7 = 31 - clz32(suspendedLanes), - lane = 1 << index$7; - root[index$7] = -1; + var index$11 = 31 - clz32(suspendedLanes), + lane = 1 << index$11; + root[index$11] = -1; suspendedLanes &= ~lane; } } @@ -6644,12 +6305,17 @@ function performSyncWorkOnRoot(root) { if (0 !== (executionContext & 48)) throw Error("Should not already be working."); flushPassiveEffects(); - var lanes = + if ( root === workInProgressRoot && 0 !== (root.expiredLanes & workInProgressRootRenderLanes) - ? workInProgressRootRenderLanes - : getNextLanes(root, 0); - var exitStatus = renderRootSync(root, lanes); + ) { + var lanes = workInProgressRootRenderLanes; + var exitStatus = renderRootSync(root, lanes); + 0 !== (workInProgressRootIncludedLanes & workInProgressRootUpdatedLanes) && + ((lanes = getNextLanes(root, lanes)), + (exitStatus = renderRootSync(root, lanes))); + } else + (lanes = getNextLanes(root, 0)), (exitStatus = renderRootSync(root, lanes)); 0 !== root.tag && 2 === exitStatus && ((executionContext |= 64), @@ -6668,6 +6334,11 @@ function performSyncWorkOnRoot(root) { ensureRootIsScheduled(root, now()); return null; } +function pushRenderLanes(fiber, lanes) { + push(subtreeRenderLanesCursor, subtreeRenderLanes); + subtreeRenderLanes |= lanes; + workInProgressRootIncludedLanes |= lanes; +} function popRenderLanes() { subtreeRenderLanes = subtreeRenderLanesCursor.current; pop(subtreeRenderLanesCursor); @@ -6707,7 +6378,7 @@ function prepareFreshStack(root, lanes) { pop(suspenseStackCursor); break; case 10: - popProvider(interruptedWork.type._context); + popProvider(interruptedWork); break; case 22: case 23: @@ -6717,29 +6388,10 @@ function prepareFreshStack(root, lanes) { } workInProgressRoot = root; workInProgress = createWorkInProgress(root.current, null); - workInProgressRootRenderLanes = subtreeRenderLanes = lanes; + workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes; workInProgressRootExitStatus = 0; workInProgressRootFatalError = null; workInProgressRootPingedLanes = workInProgressRootUpdatedLanes = workInProgressRootSkippedLanes = 0; - if (null !== interleavedQueues) { - for (root = 0; root < interleavedQueues.length; root++) - if ( - ((lanes = interleavedQueues[root]), - (timeoutHandle = lanes.interleaved), - null !== timeoutHandle) - ) { - lanes.interleaved = null; - interruptedWork = timeoutHandle.next; - var lastPendingUpdate = lanes.pending; - if (null !== lastPendingUpdate) { - var firstPendingUpdate = lastPendingUpdate.next; - lastPendingUpdate.next = interruptedWork; - timeoutHandle.next = firstPendingUpdate; - } - lanes.pending = timeoutHandle; - } - interleavedQueues = null; - } spawnedWorkDuringRender = null; } function handleError(root$jscomp$0, thrownValue) { @@ -6770,7 +6422,7 @@ function handleError(root$jscomp$0, thrownValue) { workInProgress = null; break; } - erroredWork.mode & 4 && + erroredWork.mode & 8 && stopProfilerTimerIfRunningAndRecordDelta(erroredWork, !0); a: { var root = root$jscomp$0, @@ -6778,18 +6430,15 @@ function handleError(root$jscomp$0, thrownValue) { sourceFiber = erroredWork, value = thrownValue; thrownValue = workInProgressRootRenderLanes; - sourceFiber.flags |= 8192; + sourceFiber.flags |= 4096; + sourceFiber.firstEffect = sourceFiber.lastEffect = null; if ( null !== value && "object" === typeof value && "function" === typeof value.then ) { - var wakeable = value, - tag = sourceFiber.tag; - if ( - 0 === (sourceFiber.mode & 1) && - (0 === tag || 11 === tag || 15 === tag) - ) { + var wakeable = value; + if (0 === (sourceFiber.mode & 2)) { var currentSource = sourceFiber.alternate; currentSource ? ((sourceFiber.updateQueue = currentSource.updateQueue), @@ -6800,15 +6449,15 @@ function handleError(root$jscomp$0, thrownValue) { } var hasInvisibleParentBoundary = 0 !== (suspenseStackCursor.current & 1), - workInProgress$79 = returnFiber; + workInProgress$77 = returnFiber; do { var JSCompiler_temp; - if ((JSCompiler_temp = 13 === workInProgress$79.tag)) { - var nextState = workInProgress$79.memoizedState; + if ((JSCompiler_temp = 13 === workInProgress$77.tag)) { + var nextState = workInProgress$77.memoizedState; if (null !== nextState) JSCompiler_temp = null !== nextState.dehydrated ? !0 : !1; else { - var props = workInProgress$79.memoizedProps; + var props = workInProgress$77.memoizedProps; JSCompiler_temp = void 0 === props.fallback ? !1 @@ -6820,19 +6469,16 @@ function handleError(root$jscomp$0, thrownValue) { } } if (JSCompiler_temp) { - var wakeables = workInProgress$79.updateQueue; + var wakeables = workInProgress$77.updateQueue; if (null === wakeables) { var updateQueue = new Set(); updateQueue.add(wakeable); - workInProgress$79.updateQueue = updateQueue; + workInProgress$77.updateQueue = updateQueue; } else wakeables.add(wakeable); - if ( - 0 === (workInProgress$79.mode & 1) && - workInProgress$79 !== returnFiber - ) { - workInProgress$79.flags |= 128; - sourceFiber.flags |= 65536; - sourceFiber.flags &= -10053; + if (0 === (workInProgress$77.mode & 2)) { + workInProgress$77.flags |= 64; + sourceFiber.flags |= 32768; + sourceFiber.flags &= -5029; if (1 === sourceFiber.tag) if (null === sourceFiber.alternate) sourceFiber.tag = 17; else { @@ -6863,12 +6509,12 @@ function handleError(root$jscomp$0, thrownValue) { ); wakeable.then(ping, ping); } - workInProgress$79.flags |= 16384; - workInProgress$79.lanes = thrownValue; + workInProgress$77.flags |= 8192; + workInProgress$77.lanes = thrownValue; break a; } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); value = Error( (getComponentName(sourceFiber.type) || "A React component") + " suspended while rendering, but no fallback UI was specified.\n\nAdd a component higher in the tree to provide a loading indicator or placeholder to display." @@ -6877,47 +6523,47 @@ function handleError(root$jscomp$0, thrownValue) { 5 !== workInProgressRootExitStatus && (workInProgressRootExitStatus = 2); value = createCapturedValue(value, sourceFiber); - workInProgress$79 = returnFiber; + workInProgress$77 = returnFiber; do { - switch (workInProgress$79.tag) { + switch (workInProgress$77.tag) { case 3: root = value; - workInProgress$79.flags |= 16384; + workInProgress$77.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$80 = createRootErrorUpdate( - workInProgress$79, + workInProgress$77.lanes |= thrownValue; + var update$78 = createRootErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$80); + enqueueCapturedUpdate(workInProgress$77, update$78); break a; case 1: root = value; - var ctor = workInProgress$79.type, - instance = workInProgress$79.stateNode; + var ctor = workInProgress$77.type, + instance = workInProgress$77.stateNode; if ( - 0 === (workInProgress$79.flags & 128) && + 0 === (workInProgress$77.flags & 64) && ("function" === typeof ctor.getDerivedStateFromError || (null !== instance && "function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance)))) ) { - workInProgress$79.flags |= 16384; + workInProgress$77.flags |= 8192; thrownValue &= -thrownValue; - workInProgress$79.lanes |= thrownValue; - var update$83 = createClassErrorUpdate( - workInProgress$79, + workInProgress$77.lanes |= thrownValue; + var update$81 = createClassErrorUpdate( + workInProgress$77, root, thrownValue ); - enqueueCapturedUpdate(workInProgress$79, update$83); + enqueueCapturedUpdate(workInProgress$77, update$81); break a; } } - workInProgress$79 = workInProgress$79.return; - } while (null !== workInProgress$79); + workInProgress$77 = workInProgress$77.return; + } while (null !== workInProgress$77); } completeUnitOfWork(erroredWork); } catch (yetAnotherThrownValue) { @@ -6976,7 +6622,7 @@ function workLoopConcurrent() { } function performUnitOfWork(unitOfWork) { var current = unitOfWork.alternate; - 0 !== (unitOfWork.mode & 4) + 0 !== (unitOfWork.mode & 8) ? ((profilerStartTime = now$1()), 0 > unitOfWork.actualStartTime && (unitOfWork.actualStartTime = now$1()), (current = beginWork$1(current, unitOfWork, subtreeRenderLanes)), @@ -6993,8 +6639,8 @@ function completeUnitOfWork(unitOfWork) { do { var current = completedWork.alternate; unitOfWork = completedWork.return; - if (0 === (completedWork.flags & 8192)) { - if (0 === (completedWork.mode & 4)) + if (0 === (completedWork.flags & 4096)) { + if (0 === (completedWork.mode & 8)) current = completeWork(current, completedWork, subtreeRenderLanes); else { var fiber = completedWork; @@ -7007,14 +6653,65 @@ function completeUnitOfWork(unitOfWork) { workInProgress = current; return; } + current = completedWork; + if ( + (23 !== current.tag && 22 !== current.tag) || + null === current.memoizedState || + 0 !== (subtreeRenderLanes & 1073741824) || + 0 === (current.mode & 4) + ) { + fiber = 0; + if (0 !== (current.mode & 8)) { + for ( + var actualDuration = current.actualDuration, + treeBaseDuration = current.selfBaseDuration, + shouldBubbleActualDurations = + null === current.alternate || + current.child !== current.alternate.child, + child = current.child; + null !== child; + + ) + (fiber |= child.lanes | child.childLanes), + shouldBubbleActualDurations && + (actualDuration += child.actualDuration), + (treeBaseDuration += child.treeBaseDuration), + (child = child.sibling); + 13 === current.tag && + null !== current.memoizedState && + ((shouldBubbleActualDurations = current.child), + null !== shouldBubbleActualDurations && + (treeBaseDuration -= + shouldBubbleActualDurations.treeBaseDuration)); + current.actualDuration = actualDuration; + current.treeBaseDuration = treeBaseDuration; + } else + for (actualDuration = current.child; null !== actualDuration; ) + (fiber |= actualDuration.lanes | actualDuration.childLanes), + (actualDuration = actualDuration.sibling); + current.childLanes = fiber; + } + null !== unitOfWork && + 0 === (unitOfWork.flags & 4096) && + (null === unitOfWork.firstEffect && + (unitOfWork.firstEffect = completedWork.firstEffect), + null !== completedWork.lastEffect && + (null !== unitOfWork.lastEffect && + (unitOfWork.lastEffect.nextEffect = completedWork.firstEffect), + (unitOfWork.lastEffect = completedWork.lastEffect)), + 1 < completedWork.flags && + (null !== unitOfWork.lastEffect + ? (unitOfWork.lastEffect.nextEffect = completedWork) + : (unitOfWork.firstEffect = completedWork), + (unitOfWork.lastEffect = completedWork))); } else { current = unwindWork(completedWork); if (null !== current) { - current.flags &= 8191; + current.flags &= 4095; workInProgress = current; return; } - if (0 !== (completedWork.mode & 4)) { + if (0 !== (completedWork.mode & 8)) { stopProfilerTimerIfRunningAndRecordDelta(completedWork, !1); current = completedWork.actualDuration; for (fiber = completedWork.child; null !== fiber; ) @@ -7022,9 +6719,8 @@ function completeUnitOfWork(unitOfWork) { completedWork.actualDuration = current; } null !== unitOfWork && - ((unitOfWork.flags |= 8192), - (unitOfWork.subtreeFlags = 0), - (unitOfWork.deletions = null)); + ((unitOfWork.firstEffect = unitOfWork.lastEffect = null), + (unitOfWork.flags |= 4096)); } completedWork = completedWork.sibling; if (null !== completedWork) { @@ -7055,65 +6751,190 @@ function commitRootImpl(root, renderPriorityLevel) { "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." ); root.callbackNode = null; - root.callbackPriority = 0; - var remainingLanes = finishedWork.lanes | finishedWork.childLanes; - markRootFinished(root, remainingLanes); + var remainingLanes = finishedWork.lanes | finishedWork.childLanes, + remainingLanes$jscomp$0 = remainingLanes, + noLongerPendingLanes = root.pendingLanes & ~remainingLanes$jscomp$0; + root.pendingLanes = remainingLanes$jscomp$0; + root.suspendedLanes = 0; + root.pingedLanes = 0; + root.expiredLanes &= remainingLanes$jscomp$0; + root.mutableReadLanes &= remainingLanes$jscomp$0; + root.entangledLanes &= remainingLanes$jscomp$0; + remainingLanes$jscomp$0 = root.entanglements; + for ( + var eventTimes = root.eventTimes, expirationTimes = root.expirationTimes; + 0 < noLongerPendingLanes; + + ) { + var index$12 = 31 - clz32(noLongerPendingLanes), + lane = 1 << index$12; + remainingLanes$jscomp$0[index$12] = 0; + eventTimes[index$12] = -1; + expirationTimes[index$12] = -1; + noLongerPendingLanes &= ~lane; + } null !== rootsWithPendingDiscreteUpdates && - 0 === (remainingLanes & 8) && + 0 === (remainingLanes & 24) && rootsWithPendingDiscreteUpdates.has(root) && rootsWithPendingDiscreteUpdates.delete(root); root === workInProgressRoot && ((workInProgress = workInProgressRoot = null), (workInProgressRootRenderLanes = 0)); - (0 === (finishedWork.subtreeFlags & 1040) && - 0 === (finishedWork.flags & 1040)) || - rootDoesHavePassiveEffects || - ((rootDoesHavePassiveEffects = !0), - scheduleCallback(97, function() { - flushPassiveEffects(); - return null; - })); - remainingLanes = 0 !== (finishedWork.flags & 8054); - if (0 !== (finishedWork.subtreeFlags & 8054) || remainingLanes) { - remainingLanes = executionContext; + 1 < finishedWork.flags + ? null !== finishedWork.lastEffect + ? ((finishedWork.lastEffect.nextEffect = finishedWork), + (remainingLanes = finishedWork.firstEffect)) + : (remainingLanes = finishedWork) + : (remainingLanes = finishedWork.firstEffect); + if (null !== remainingLanes) { + remainingLanes$jscomp$0 = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root); - ReactCurrentOwner$2.current = null; - commitBeforeMutationEffects(root, finishedWork); + eventTimes = pushInteractions(root); + focusedInstanceHandle = ReactCurrentOwner$2.current = null; + shouldFireAfterActiveInstanceBlur = !1; + nextEffect = remainingLanes; + do + try { + commitBeforeMutationEffects(); + } catch (error) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + focusedInstanceHandle = null; commitTime = now$1(); - commitMutationEffects(root, renderPriorityLevel, finishedWork); + nextEffect = remainingLanes; + do + try { + for (expirationTimes = root; null !== nextEffect; ) { + var flags = nextEffect.flags; + if (flags & 128) { + var current = nextEffect.alternate; + if (null !== current) { + var currentRef = current.ref; + null !== currentRef && + ("function" === typeof currentRef + ? currentRef(null) + : (currentRef.current = null)); + } + } + switch (flags & 1038) { + case 2: + commitPlacement(nextEffect); + nextEffect.flags &= -3; + break; + case 6: + commitPlacement(nextEffect); + nextEffect.flags &= -3; + commitWork(nextEffect.alternate, nextEffect); + break; + case 1024: + nextEffect.flags &= -1025; + break; + case 1028: + nextEffect.flags &= -1025; + commitWork(nextEffect.alternate, nextEffect); + break; + case 4: + commitWork(nextEffect.alternate, nextEffect); + break; + case 8: + noLongerPendingLanes = nextEffect; + unmountHostComponents(expirationTimes, noLongerPendingLanes); + var alternate = noLongerPendingLanes.alternate; + detachFiberMutation(noLongerPendingLanes); + null !== alternate && detachFiberMutation(alternate); + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$91) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$91); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); root.current = finishedWork; - commitLayoutEffects(finishedWork, root, lanes); + nextEffect = remainingLanes; + do + try { + for (flags = root; null !== nextEffect; ) { + var flags$jscomp$0 = nextEffect.flags; + flags$jscomp$0 & 36 && + commitLifeCycles(flags, nextEffect.alternate, nextEffect); + if (flags$jscomp$0 & 128) { + current = void 0; + var ref = nextEffect.ref; + if (null !== ref) { + var instance = nextEffect.stateNode; + switch (nextEffect.tag) { + case 5: + current = instance; + break; + default: + current = instance; + } + "function" === typeof ref + ? ref(current) + : (ref.current = current); + } + } + nextEffect = nextEffect.nextEffect; + } + } catch (error$92) { + if (null === nextEffect) throw Error("Should be working on an effect."); + captureCommitPhaseError(nextEffect, error$92); + nextEffect = nextEffect.nextEffect; + } + while (null !== nextEffect); + nextEffect = null; requestPaint(); - tracing.__interactionsRef.current = prevInteractions; - executionContext = remainingLanes; + tracing.__interactionsRef.current = eventTimes; + executionContext = remainingLanes$jscomp$0; } else (root.current = finishedWork), (commitTime = now$1()); - if ((prevInteractions = rootDoesHavePassiveEffects)) + if ((flags$jscomp$0 = rootDoesHavePassiveEffects)) (rootDoesHavePassiveEffects = !1), (rootWithPendingPassiveEffects = root), (pendingPassiveEffectsLanes = lanes), (pendingPassiveEffectsRenderPriority = renderPriorityLevel); + else + for (nextEffect = remainingLanes; null !== nextEffect; ) + (ref = nextEffect.nextEffect), + (nextEffect.nextEffect = null), + nextEffect.flags & 8 && + ((instance = nextEffect), + (instance.sibling = null), + (instance.stateNode = null)), + (nextEffect = ref); remainingLanes = root.pendingLanes; if (0 !== remainingLanes) { - if (null !== spawnedWorkDuringRender) { - var expirationTimes = spawnedWorkDuringRender; - spawnedWorkDuringRender = null; - for (var i = 0; i < expirationTimes.length; i++) - scheduleInteractions( - root, - expirationTimes[i], - root.memoizedInteractions - ); - } + if (null !== spawnedWorkDuringRender) + for ( + ref = spawnedWorkDuringRender, + spawnedWorkDuringRender = null, + instance = 0; + instance < ref.length; + instance++ + ) + scheduleInteractions(root, ref[instance], root.memoizedInteractions); schedulePendingInteractions(root, remainingLanes); } else legacyErrorBoundariesThatAlreadyFailed = null; - prevInteractions || finishPendingInteractions(root, lanes); - 0 !== (remainingLanes & 1) + flags$jscomp$0 || finishPendingInteractions(root, lanes); + 1 === remainingLanes ? root === rootWithNestedUpdates ? nestedUpdateCount++ : ((nestedUpdateCount = 0), (rootWithNestedUpdates = root)) : (nestedUpdateCount = 0); - onCommitRoot(finishedWork.stateNode, renderPriorityLevel); + finishedWork = finishedWork.stateNode; + if (injectedHook && "function" === typeof injectedHook.onCommitFiberRoot) + try { + injectedHook.onCommitFiberRoot( + rendererID, + finishedWork, + renderPriorityLevel, + 64 === (finishedWork.current.flags & 64) + ); + } catch (err) {} ensureRootIsScheduled(root, now()); if (hasUncaughtError) throw ((hasUncaughtError = !1), @@ -7124,6 +6945,30 @@ function commitRootImpl(root, renderPriorityLevel) { flushSyncCallbackQueue(); return null; } +function commitBeforeMutationEffects() { + for (; null !== nextEffect; ) { + var current = nextEffect.alternate; + shouldFireAfterActiveInstanceBlur || + null === focusedInstanceHandle || + (0 !== (nextEffect.flags & 8) + ? doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0) + : 13 === nextEffect.tag && + isSuspenseBoundaryBeingHidden(current, nextEffect) && + doesFiberContain(nextEffect, focusedInstanceHandle) && + (shouldFireAfterActiveInstanceBlur = !0)); + var flags = nextEffect.flags; + 0 !== (flags & 256) && commitBeforeMutationLifeCycles(current, nextEffect); + 0 === (flags & 512) || + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); + nextEffect = nextEffect.nextEffect; + } +} function flushPassiveEffects() { if (90 !== pendingPassiveEffectsRenderPriority) { var priorityLevel = @@ -7135,6 +6980,24 @@ function flushPassiveEffects() { } return !1; } +function enqueuePendingPassiveHookEffectMount(fiber, effect) { + pendingPassiveHookEffectsMount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} +function enqueuePendingPassiveHookEffectUnmount(fiber, effect) { + pendingPassiveHookEffectsUnmount.push(effect, fiber); + rootDoesHavePassiveEffects || + ((rootDoesHavePassiveEffects = !0), + scheduleCallback(97, function() { + flushPassiveEffects(); + return null; + })); +} function flushPassiveEffectsImpl() { if (null === rootWithPendingPassiveEffects) return !1; var root = rootWithPendingPassiveEffects, @@ -7145,104 +7008,41 @@ function flushPassiveEffectsImpl() { throw Error("Cannot flush passive effects while already rendering."); var prevExecutionContext = executionContext; executionContext |= 32; - var prevInteractions = pushInteractions(root); - for (nextEffect = root.current; null !== nextEffect; ) { - var fiber = nextEffect, - child = fiber.child; - if (0 !== (nextEffect.flags & 16)) { - var deletions = fiber.deletions; - if (null !== deletions) { - for (var i = 0; i < deletions.length; i++) { - var fiberToDelete = deletions[i]; - for (nextEffect = fiberToDelete; null !== nextEffect; ) { - var fiber$jscomp$0 = nextEffect; - switch (fiber$jscomp$0.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(4, fiber$jscomp$0, fiber); - } - var child$jscomp$0 = fiber$jscomp$0.child; - if (null !== child$jscomp$0) - (child$jscomp$0.return = fiber$jscomp$0), - (nextEffect = child$jscomp$0); - else - for (; null !== nextEffect; ) { - fiber$jscomp$0 = nextEffect; - if (fiber$jscomp$0 === fiberToDelete) { - nextEffect = null; - break; - } - child$jscomp$0 = fiber$jscomp$0.sibling; - if (null !== child$jscomp$0) { - child$jscomp$0.return = fiber$jscomp$0.return; - nextEffect = child$jscomp$0; - break; - } - nextEffect = fiber$jscomp$0.return; - } - } - fiber$jscomp$0 = fiberToDelete.alternate; - detachFiberAfterEffects(fiberToDelete); - null !== fiber$jscomp$0 && detachFiberAfterEffects(fiber$jscomp$0); - } - nextEffect = fiber; + var prevInteractions = pushInteractions(root), + unmountEffects = pendingPassiveHookEffectsUnmount; + pendingPassiveHookEffectsUnmount = []; + for (var i = 0; i < unmountEffects.length; i += 2) { + var effect$97 = unmountEffects[i], + fiber = unmountEffects[i + 1], + destroy = effect$97.destroy; + effect$97.destroy = void 0; + if ("function" === typeof destroy) + try { + destroy(); + } catch (error) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error); } + } + unmountEffects = pendingPassiveHookEffectsMount; + pendingPassiveHookEffectsMount = []; + for (i = 0; i < unmountEffects.length; i += 2) { + effect$97 = unmountEffects[i]; + fiber = unmountEffects[i + 1]; + try { + var create$101 = effect$97.create; + effect$97.destroy = create$101(); + } catch (error$102) { + if (null === fiber) throw Error("Should be working on an effect."); + captureCommitPhaseError(fiber, error$102); } - if (0 !== (fiber.subtreeFlags & 1040) && null !== child) - (child.return = fiber), (nextEffect = child); - else - a: for (; null !== nextEffect; ) { - fiber = nextEffect; - if (0 !== (fiber.flags & 1024)) - switch (fiber.tag) { - case 0: - case 11: - case 15: - commitHookEffectListUnmount(5, fiber, fiber.return); - } - child = fiber.sibling; - if (null !== child) { - child.return = fiber.return; - nextEffect = child; - break a; - } - nextEffect = fiber.return; - } } - for (nextEffect = fiber = root.current; null !== nextEffect; ) - if ( - ((child = nextEffect), - (deletions = child.child), - 0 !== (child.subtreeFlags & 1040) && null !== deletions) - ) - (deletions.return = child), (nextEffect = deletions); - else - a: for (child = fiber; null !== nextEffect; ) { - deletions = nextEffect; - if (0 !== (deletions.flags & 1024)) - try { - switch (deletions.tag) { - case 0: - case 11: - case 15: - commitHookEffectListMount(5, deletions); - } - } catch (error) { - captureCommitPhaseError(deletions, deletions.return, error); - } - if (deletions === child) { - nextEffect = null; - break a; - } - i = deletions.sibling; - if (null !== i) { - i.return = deletions.return; - nextEffect = i; - break a; - } - nextEffect = deletions.return; - } + for (unmountEffects = root.current.firstEffect; null !== unmountEffects; ) + (create$101 = unmountEffects.nextEffect), + (unmountEffects.nextEffect = null), + unmountEffects.flags & 8 && + ((unmountEffects.sibling = null), (unmountEffects.stateNode = null)), + (unmountEffects = create$101); tracing.__interactionsRef.current = prevInteractions; finishPendingInteractions(root, lanes); executionContext = prevExecutionContext; @@ -7260,51 +7060,43 @@ function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) { ensureRootIsScheduled(rootFiber, sourceFiber), schedulePendingInteractions(rootFiber, 1)); } -function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error) { +function captureCommitPhaseError(sourceFiber, error) { if (3 === sourceFiber.tag) captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error); else - for ( - nearestMountedAncestor = sourceFiber.return; - null !== nearestMountedAncestor; - - ) { - if (3 === nearestMountedAncestor.tag) { - captureCommitPhaseErrorOnRoot( - nearestMountedAncestor, - sourceFiber, - error - ); + for (var fiber = sourceFiber.return; null !== fiber; ) { + if (3 === fiber.tag) { + captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error); break; - } else if (1 === nearestMountedAncestor.tag) { - var instance = nearestMountedAncestor.stateNode; + } else if (1 === fiber.tag) { + var instance = fiber.stateNode; if ( - "function" === - typeof nearestMountedAncestor.type.getDerivedStateFromError || + "function" === typeof fiber.type.getDerivedStateFromError || ("function" === typeof instance.componentDidCatch && (null === legacyErrorBoundariesThatAlreadyFailed || !legacyErrorBoundariesThatAlreadyFailed.has(instance))) ) { sourceFiber = createCapturedValue(error, sourceFiber); - sourceFiber = createClassErrorUpdate( - nearestMountedAncestor, - sourceFiber, - 1 - ); - enqueueUpdate(nearestMountedAncestor, sourceFiber); - sourceFiber = requestEventTime(); - nearestMountedAncestor = markUpdateLaneFromFiberToRoot( - nearestMountedAncestor, - 1 - ); - null !== nearestMountedAncestor && - (markRootUpdated(nearestMountedAncestor, 1, sourceFiber), - ensureRootIsScheduled(nearestMountedAncestor, sourceFiber), - schedulePendingInteractions(nearestMountedAncestor, 1)); + var update = createClassErrorUpdate(fiber, sourceFiber, 1); + enqueueUpdate(fiber, update); + update = requestEventTime(); + fiber = markUpdateLaneFromFiberToRoot(fiber, 1); + if (null !== fiber) + markRootUpdated(fiber, 1, update), + ensureRootIsScheduled(fiber, update), + schedulePendingInteractions(fiber, 1); + else if ( + "function" === typeof instance.componentDidCatch && + (null === legacyErrorBoundariesThatAlreadyFailed || + !legacyErrorBoundariesThatAlreadyFailed.has(instance)) + ) + try { + instance.componentDidCatch(error, sourceFiber); + } catch (errorToIgnore) {} break; } } - nearestMountedAncestor = nearestMountedAncestor.return; + fiber = fiber.return; } } function pingSuspendedRoot(root, wakeable, pingedLanes) { @@ -7316,7 +7108,7 @@ function pingSuspendedRoot(root, wakeable, pingedLanes) { (workInProgressRootRenderLanes & pingedLanes) === pingedLanes && (4 === workInProgressRootExitStatus || (3 === workInProgressRootExitStatus && - (workInProgressRootRenderLanes & 125829120) === + (workInProgressRootRenderLanes & 62914560) === workInProgressRootRenderLanes && 500 > now() - globalMostRecentFallbackTime) ? prepareFreshStack(root, 0) @@ -7330,13 +7122,14 @@ function resolveRetryWakeable(boundaryFiber, wakeable) { wakeable = 0; 0 === wakeable && ((wakeable = boundaryFiber.mode), - 0 === (wakeable & 1) + 0 === (wakeable & 2) ? (wakeable = 1) - : 0 === (wakeable & 2) + : 0 === (wakeable & 4) ? (wakeable = 99 === getCurrentPriorityLevel() ? 1 : 2) - : ((wakeable = nextRetryLane), - (nextRetryLane <<= 1), - 0 === (nextRetryLane & 125829120) && (nextRetryLane = 8388608))); + : (0 === currentEventWipLanes && + (currentEventWipLanes = workInProgressRootIncludedLanes), + (wakeable = getHighestPriorityLane(62914560 & ~currentEventWipLanes)), + 0 === wakeable && (wakeable = 4194304))); retryCache = requestEventTime(); boundaryFiber = markUpdateLaneFromFiberToRoot(boundaryFiber, wakeable); null !== boundaryFiber && @@ -7353,90 +7146,85 @@ beginWork$1 = function(current, workInProgress, renderLanes) { didPerformWorkStackCursor.current ) didReceiveUpdate = !0; + else if (0 !== (renderLanes & updateLanes)) + didReceiveUpdate = 0 !== (current.flags & 32768) ? !0 : !1; 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( + 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.memoizedProps.value; + var context = workInProgress.type._context; + push(valueCursor, context._currentValue); + context._currentValue = updateLanes; + 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 ); - 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) + workInProgress = bailoutOnAlreadyFinishedWork( + current, + workInProgress, + renderLanes ); - } - return 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 & 64)) { + if (updateLanes) + return updateSuspenseListComponent( + current, + workInProgress, + renderLanes + ); + workInProgress.flags |= 64; + } + context = workInProgress.memoizedState; + null !== context && + ((context.rendering = null), + (context.tail = null), + (context.lastEffect = null)); + push(suspenseStackCursor, suspenseStackCursor.current); + if (updateLanes) break; + else return null; + case 22: + case 23: + return ( + (workInProgress.lanes = 0), + updateOffscreenComponent(current, workInProgress, renderLanes) + ); } - didReceiveUpdate = 0 !== (current.flags & 65536) ? !0 : !1; + return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes); } else didReceiveUpdate = !1; workInProgress.lanes = 0; @@ -7448,22 +7236,22 @@ beginWork$1 = function(current, workInProgress, renderLanes) { (workInProgress.alternate = null), (workInProgress.flags |= 2)); current = workInProgress.pendingProps; - nextValue = getMaskedContext(workInProgress, contextStackCursor.current); + context = getMaskedContext(workInProgress, contextStackCursor.current); prepareToReadContext(workInProgress, renderLanes); - nextValue = renderWithHooks( + context = renderWithHooks( null, workInProgress, updateLanes, 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; @@ -7473,8 +7261,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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); var getDerivedStateFromProps = updateLanes.getDerivedStateFromProps; @@ -7485,9 +7273,9 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps, current ); - nextValue.updater = classComponentUpdater; - workInProgress.stateNode = nextValue; - nextValue._reactInternals = workInProgress; + context.updater = classComponentUpdater; + workInProgress.stateNode = context; + context._reactInternals = workInProgress; mountClassInstance(workInProgress, updateLanes, current, renderLanes); workInProgress = finishClassComponent( null, @@ -7499,28 +7287,28 @@ beginWork$1 = function(current, workInProgress, 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; + context = 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); + hasContext = context._init; + context = hasContext(context._payload); + workInProgress.type = context; + hasContext = workInProgress.tag = resolveLazyComponentTag(context); + current = resolveDefaultProps(context, current); switch (hasContext) { case 0: workInProgress = updateFunctionComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7529,7 +7317,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateClassComponent( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7538,7 +7326,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateForwardRef( null, workInProgress, - nextValue, + context, current, renderLanes ); @@ -7547,8 +7335,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { workInProgress = updateMemoComponent( null, workInProgress, - nextValue, - resolveDefaultProps(nextValue.type, current), + context, + resolveDefaultProps(context.type, current), updateLanes, renderLanes ); @@ -7556,7 +7344,7 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } throw Error( "Element type is invalid. Received a promise that resolves to: " + - nextValue + + context + ". Lazy element type must resolve to a class or function." ); } @@ -7564,32 +7352,32 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 0: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateFunctionComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); case 1: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateClassComponent( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7600,18 +7388,19 @@ beginWork$1 = function(current, workInProgress, renderLanes) { 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; + updateLanes = workInProgress.pendingProps; + context = workInProgress.memoizedState; + context = null !== context ? context.element : null; cloneUpdateQueue(current, workInProgress); - processUpdateQueue(workInProgress, nextValue, null, renderLanes); - nextValue = workInProgress.memoizedState.element; - nextValue === updateLanes + processUpdateQueue(workInProgress, updateLanes, null, renderLanes); + updateLanes = workInProgress.memoizedState.element; + updateLanes === context ? (workInProgress = bailoutOnAlreadyFinishedWork( current, workInProgress, renderLanes )) - : (reconcileChildren(current, workInProgress, nextValue, renderLanes), + : (reconcileChildren(current, workInProgress, updateLanes, renderLanes), (workInProgress = workInProgress.child)); return workInProgress; case 5: @@ -7651,16 +7440,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 11: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), updateForwardRef( current, workInProgress, updateLanes, - nextValue, + context, renderLanes ) ); @@ -7701,21 +7490,27 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 10: a: { updateLanes = workInProgress.type._context; - nextValue = workInProgress.pendingProps; + context = workInProgress.pendingProps; getDerivedStateFromProps = workInProgress.memoizedProps; - hasContext = nextValue.value; - push(valueCursor, updateLanes._currentValue); - updateLanes._currentValue = hasContext; - if (null !== getDerivedStateFromProps) { - var oldValue = getDerivedStateFromProps.value; - hasContext = objectIs(oldValue, hasContext) - ? 0 - : ("function" === typeof updateLanes._calculateChangedBits - ? updateLanes._calculateChangedBits(oldValue, hasContext) - : 1073741823) | 0; - if (0 === hasContext) { + hasContext = context.value; + var context$jscomp$0 = workInProgress.type._context; + push(valueCursor, context$jscomp$0._currentValue); + context$jscomp$0._currentValue = hasContext; + if (null !== getDerivedStateFromProps) + if ( + ((context$jscomp$0 = getDerivedStateFromProps.value), + (hasContext = objectIs(context$jscomp$0, hasContext) + ? 0 + : ("function" === typeof updateLanes._calculateChangedBits + ? updateLanes._calculateChangedBits( + context$jscomp$0, + hasContext + ) + : 1073741823) | 0), + 0 === hasContext) + ) { if ( - getDerivedStateFromProps.children === nextValue.children && + getDerivedStateFromProps.children === context.children && !didPerformWorkStackCursor.current ) { workInProgress = bailoutOnAlreadyFinishedWork( @@ -7727,14 +7522,15 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else for ( - oldValue = workInProgress.child, - null !== oldValue && (oldValue.return = workInProgress); - null !== oldValue; + context$jscomp$0 = workInProgress.child, + null !== context$jscomp$0 && + (context$jscomp$0.return = workInProgress); + null !== context$jscomp$0; ) { - var list = oldValue.dependencies; + var list = context$jscomp$0.dependencies; if (null !== list) { - getDerivedStateFromProps = oldValue.child; + getDerivedStateFromProps = context$jscomp$0.child; for ( var dependency = list.firstContext; null !== dependency; @@ -7744,24 +7540,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { dependency.context === updateLanes && 0 !== (dependency.observedBits & hasContext) ) { - if (1 === oldValue.tag) { - dependency = createUpdate(-1, renderLanes & -renderLanes); - dependency.tag = 2; - var updateQueue = oldValue.updateQueue; - if (null !== updateQueue) { - updateQueue = updateQueue.shared; - var pending = updateQueue.pending; - null === pending - ? (dependency.next = dependency) - : ((dependency.next = pending.next), - (pending.next = dependency)); - updateQueue.pending = dependency; - } - } - oldValue.lanes |= renderLanes; - dependency = oldValue.alternate; + 1 === context$jscomp$0.tag && + ((dependency = createUpdate( + -1, + renderLanes & -renderLanes + )), + (dependency.tag = 2), + enqueueUpdate(context$jscomp$0, dependency)); + context$jscomp$0.lanes |= renderLanes; + dependency = context$jscomp$0.alternate; null !== dependency && (dependency.lanes |= renderLanes); - scheduleWorkOnParentPath(oldValue.return, renderLanes); + scheduleWorkOnParentPath( + context$jscomp$0.return, + renderLanes + ); list.lanes |= renderLanes; break; } @@ -7769,16 +7561,16 @@ beginWork$1 = function(current, workInProgress, renderLanes) { } } else getDerivedStateFromProps = - 10 === oldValue.tag - ? oldValue.type === workInProgress.type + 10 === context$jscomp$0.tag + ? context$jscomp$0.type === workInProgress.type ? null - : oldValue.child - : oldValue.child; + : context$jscomp$0.child + : context$jscomp$0.child; if (null !== getDerivedStateFromProps) - getDerivedStateFromProps.return = oldValue; + getDerivedStateFromProps.return = context$jscomp$0; else for ( - getDerivedStateFromProps = oldValue; + getDerivedStateFromProps = context$jscomp$0; null !== getDerivedStateFromProps; ) { @@ -7786,21 +7578,20 @@ beginWork$1 = function(current, workInProgress, renderLanes) { getDerivedStateFromProps = null; break; } - oldValue = getDerivedStateFromProps.sibling; - if (null !== oldValue) { - oldValue.return = getDerivedStateFromProps.return; - getDerivedStateFromProps = oldValue; + context$jscomp$0 = getDerivedStateFromProps.sibling; + if (null !== context$jscomp$0) { + context$jscomp$0.return = getDerivedStateFromProps.return; + getDerivedStateFromProps = context$jscomp$0; break; } getDerivedStateFromProps = getDerivedStateFromProps.return; } - oldValue = getDerivedStateFromProps; + context$jscomp$0 = getDerivedStateFromProps; } - } reconcileChildren( current, workInProgress, - nextValue.children, + context.children, renderLanes ); workInProgress = workInProgress.child; @@ -7808,28 +7599,28 @@ beginWork$1 = function(current, workInProgress, renderLanes) { return workInProgress; case 9: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = workInProgress.pendingProps), (updateLanes = hasContext.children), prepareToReadContext(workInProgress, renderLanes), - (nextValue = readContext(nextValue, hasContext.unstable_observedBits)), - (updateLanes = updateLanes(nextValue)), + (context = readContext(context, hasContext.unstable_observedBits)), + (updateLanes = updateLanes(context)), (workInProgress.flags |= 1), reconcileChildren(current, workInProgress, updateLanes, renderLanes), workInProgress.child ); case 14: return ( - (nextValue = workInProgress.type), + (context = workInProgress.type), (hasContext = resolveDefaultProps( - nextValue, + context, workInProgress.pendingProps )), - (hasContext = resolveDefaultProps(nextValue.type, hasContext)), + (hasContext = resolveDefaultProps(context.type, hasContext)), updateMemoComponent( current, workInProgress, - nextValue, + context, hasContext, updateLanes, renderLanes @@ -7847,11 +7638,11 @@ beginWork$1 = function(current, workInProgress, renderLanes) { case 17: return ( (updateLanes = workInProgress.type), - (nextValue = workInProgress.pendingProps), - (nextValue = + (context = workInProgress.pendingProps), + (context = workInProgress.elementType === updateLanes - ? nextValue - : resolveDefaultProps(updateLanes, nextValue)), + ? context + : resolveDefaultProps(updateLanes, context)), null !== current && ((current.alternate = null), (workInProgress.alternate = null), @@ -7861,8 +7652,8 @@ beginWork$1 = function(current, workInProgress, renderLanes) { ? ((current = !0), pushContextProvider(workInProgress)) : (current = !1), prepareToReadContext(workInProgress, renderLanes), - constructClassInstance(workInProgress, updateLanes, nextValue), - mountClassInstance(workInProgress, updateLanes, nextValue, renderLanes), + constructClassInstance(workInProgress, updateLanes, context), + mountClassInstance(workInProgress, updateLanes, context, renderLanes), finishClassComponent( null, workInProgress, @@ -7963,9 +7754,9 @@ function finishPendingInteractions(root, committedLanes) { if (null !== subscriber && 0 === interaction.__count) try { subscriber.onInteractionScheduledWorkCompleted(interaction); - } catch (error$96) { + } catch (error$103) { scheduleCallback(99, function() { - throw error$96; + throw error$103; }); } })); @@ -7981,8 +7772,8 @@ function FiberNode(tag, pendingProps, key, mode) { this.pendingProps = pendingProps; this.dependencies = this.memoizedState = this.updateQueue = this.memoizedProps = null; this.mode = mode; - this.subtreeFlags = this.flags = 0; - this.deletions = null; + this.flags = 0; + this.lastEffect = this.firstEffect = this.nextEffect = null; this.childLanes = this.lanes = 0; this.alternate = null; this.actualDuration = 0; @@ -8023,11 +7814,11 @@ function createWorkInProgress(current, pendingProps) { : ((workInProgress.pendingProps = pendingProps), (workInProgress.type = current.type), (workInProgress.flags = 0), - (workInProgress.subtreeFlags = 0), - (workInProgress.deletions = null), + (workInProgress.nextEffect = null), + (workInProgress.firstEffect = null), + (workInProgress.lastEffect = null), (workInProgress.actualDuration = 0), (workInProgress.actualStartTime = -1)); - workInProgress.flags = current.flags & 131072; workInProgress.childLanes = current.childLanes; workInProgress.lanes = current.lanes; workInProgress.child = current.child; @@ -8064,18 +7855,15 @@ function createFiberFromTypeAndProps( return createFiberFromFragment(pendingProps.children, mode, lanes, key); case REACT_DEBUG_TRACING_MODE_TYPE: fiberTag = 8; - mode |= 8; + mode |= 16; break; case REACT_STRICT_MODE_TYPE: fiberTag = 8; - 1 <= - (null == pendingProps.unstable_level - ? 1 - : pendingProps.unstable_level) && (mode |= 16); + mode |= 1; break; case REACT_PROFILER_TYPE: return ( - (type = createFiber(12, pendingProps, key, mode | 4)), + (type = createFiber(12, pendingProps, key, mode | 8)), (type.elementType = REACT_PROFILER_TYPE), (type.type = REACT_PROFILER_TYPE), (type.lanes = lanes), @@ -8266,8 +8054,7 @@ function updateContainer(element, container, parentComponent, callback) { callback = void 0 === callback ? null : callback; null !== callback && (container.callback = callback); enqueueUpdate(current, container); - element = scheduleUpdateOnFiber(current, lane, eventTime); - null !== element && entangleTransitions(element, current, lane); + scheduleUpdateOnFiber(current, lane, eventTime); return lane; } function emptyFindFiberByHostInstance() { @@ -8306,10 +8093,10 @@ batchedUpdatesImpl = function(fn, a) { } }; var roots = new Map(), - devToolsConfig$jscomp$inline_986 = { + devToolsConfig$jscomp$inline_930 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "17.0.2", + version: "17.0.1-454c2211c", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForViewTag: function() { @@ -8324,11 +8111,11 @@ var roots = new Map(), }.bind(null, findNodeHandle) } }; -var internals$jscomp$inline_1282 = { - bundleType: devToolsConfig$jscomp$inline_986.bundleType, - version: devToolsConfig$jscomp$inline_986.version, - rendererPackageName: devToolsConfig$jscomp$inline_986.rendererPackageName, - rendererConfig: devToolsConfig$jscomp$inline_986.rendererConfig, +var internals$jscomp$inline_1148 = { + bundleType: devToolsConfig$jscomp$inline_930.bundleType, + version: devToolsConfig$jscomp$inline_930.version, + rendererPackageName: devToolsConfig$jscomp$inline_930.rendererPackageName, + rendererConfig: devToolsConfig$jscomp$inline_930.rendererConfig, overrideHookState: null, overrideHookStateDeletePath: null, overrideHookStateRenamePath: null, @@ -8343,7 +8130,7 @@ var internals$jscomp$inline_1282 = { return null === fiber ? null : fiber.stateNode; }, findFiberByHostInstance: - devToolsConfig$jscomp$inline_986.findFiberByHostInstance || + devToolsConfig$jscomp$inline_930.findFiberByHostInstance || emptyFindFiberByHostInstance, findHostInstancesForRefresh: null, scheduleRefresh: null, @@ -8352,16 +8139,16 @@ var internals$jscomp$inline_1282 = { getCurrentFiber: null }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { - var hook$jscomp$inline_1283 = __REACT_DEVTOOLS_GLOBAL_HOOK__; + var hook$jscomp$inline_1149 = __REACT_DEVTOOLS_GLOBAL_HOOK__; if ( - !hook$jscomp$inline_1283.isDisabled && - hook$jscomp$inline_1283.supportsFiber + !hook$jscomp$inline_1149.isDisabled && + hook$jscomp$inline_1149.supportsFiber ) try { - (rendererID = hook$jscomp$inline_1283.inject( - internals$jscomp$inline_1282 + (rendererID = hook$jscomp$inline_1149.inject( + internals$jscomp$inline_1148 )), - (injectedHook = hook$jscomp$inline_1283); + (injectedHook = hook$jscomp$inline_1149); } catch (err) {} } exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { @@ -8411,7 +8198,7 @@ exports.render = function(element, containerTag, callback) { if (!root) { root = new FiberRootNode(containerTag, 0, !1); var JSCompiler_inline_result = 0; - isDevToolsPresent && (JSCompiler_inline_result |= 4); + isDevToolsPresent && (JSCompiler_inline_result |= 8); JSCompiler_inline_result = createFiber( 3, null, @@ -8420,7 +8207,6 @@ exports.render = function(element, containerTag, callback) { ); root.current = JSCompiler_inline_result; JSCompiler_inline_result.stateNode = root; - JSCompiler_inline_result.memoizedState = { element: null }; initializeUpdateQueue(JSCompiler_inline_result); roots.set(containerTag, root); } diff --git a/Libraries/Renderer/shims/ReactFabric.js b/Libraries/Renderer/shims/ReactFabric.js index 536ce9a6f30b65..31edc17fd5ee2e 100644 --- a/Libraries/Renderer/shims/ReactFabric.js +++ b/Libraries/Renderer/shims/ReactFabric.js @@ -8,8 +8,6 @@ * @flow */ -'use strict'; - import {BatchedBridge} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; // TODO @sema: Adjust types diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 462abeac94beee..552b118556aaf0 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -8,7 +8,12 @@ * @flow strict */ -import type {ElementRef, ElementType, Element, AbstractComponent} from 'react'; +import type { + ElementRef, + ElementType, + MixedElement, + AbstractComponent, +} from 'react'; export type MeasureOnSuccessCallback = ( x: number, @@ -44,7 +49,7 @@ type AttributeType = // or we allow them to define specific types and use this hack type AnyAttributeType = AttributeType<$FlowFixMe, $FlowFixMe>; -export type AttributeConfiguration = $ReadOnly<{ +type AttributeConfiguration = $ReadOnly<{ [propName: string]: AnyAttributeType, style: $ReadOnly<{ [propName: string]: AnyAttributeType, @@ -180,7 +185,7 @@ export type ReactNativeType = { eventType: string, ): void, render( - element: Element, + element: MixedElement, containerTag: number, callback: ?() => void, ): ?ElementRef, @@ -208,7 +213,7 @@ export type ReactFabricType = { eventType: string, ): void, render( - element: Element, + element: MixedElement, containerTag: number, callback: ?() => void, ): ?ElementRef, diff --git a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js index 5f219fea65208c..0b3b8cc3d01194 100644 --- a/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js +++ b/Libraries/Renderer/shims/ReactNativeViewConfigRegistry.js @@ -8,10 +8,6 @@ * @flow strict-local */ -/* eslint-disable react-internal/invariant-args */ - -'use strict'; - import {type ViewConfig} from './ReactNativeTypes'; import invariant from 'invariant'; diff --git a/Libraries/Renderer/shims/createReactNativeComponentClass.js b/Libraries/Renderer/shims/createReactNativeComponentClass.js index f8f4c9284e4c32..0f893dfd24a0b9 100644 --- a/Libraries/Renderer/shims/createReactNativeComponentClass.js +++ b/Libraries/Renderer/shims/createReactNativeComponentClass.js @@ -8,8 +8,6 @@ * @flow strict-local */ -'use strict'; - import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface'; import {type ViewConfig} from './ReactNativeTypes'; From 55c8833817c3e9cf9882a712c8b9946a262df231 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 26 Feb 2021 21:10:36 -0800 Subject: [PATCH 16/51] Bump Android compileSdkVersion and targetSdkVersion to 30 Summary: Bump Android compileSdkVersion and targetSdkVersion to 30 changelog: [Android][Changed] Bump Android compileSdkVersion and targetSdkVersion from 29 to 30 Reviewed By: ShikaSD Differential Revision: D26470604 fbshipit-source-id: ffd490f6e547d16f9832ec46cf7bd2c0689aba96 --- .circleci/config.yml | 2 +- ReactAndroid/build.gradle | 2 +- template/android/build.gradle | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ca3e88fc57bad4..9dae8d5352723a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -617,7 +617,7 @@ jobs: environment: - ANDROID_HOME: "C:\\Android\\android-sdk" - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944" - - ANDROID_BUILD_VERSION: 28 + - ANDROID_BUILD_VERSION: 30 - ANDROID_TOOLS_VERSION: 29.0.3 - GRADLE_OPTS: -Dorg.gradle.daemon=false - NDK_VERSION: 20.1.5948944 diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 8b8a05d29e4738..0944a54a9bab74 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -378,7 +378,7 @@ task extractJNIFiles { } android { - compileSdkVersion 29 + compileSdkVersion 30 ndkVersion ANDROID_NDK_VERSION compileOptions { sourceCompatibility(JavaVersion.VERSION_1_8) diff --git a/template/android/build.gradle b/template/android/build.gradle index 93232f5fca9389..ac4d64714c0bfb 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -4,8 +4,8 @@ buildscript { ext { buildToolsVersion = "29.0.3" minSdkVersion = 21 - compileSdkVersion = 29 - targetSdkVersion = 29 + compileSdkVersion = 30 + targetSdkVersion = 30 ndkVersion = "20.1.5948944" } repositories { From ee98e6a4939b85c93a3d8bf68a2ed1c5e074de6b Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 21:17:46 -0800 Subject: [PATCH 17/51] ReactCommon/nativemodule: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695016 fbshipit-source-id: 63e6f6fc919076d94f04416f6821f21e0b3707a3 --- Libraries/NativeAnimation/React-RCTAnimation.podspec | 2 +- ReactCommon/ReactCommon.podspec | 4 ++++ ReactCommon/react/debug/Android.mk | 2 ++ ReactCommon/react/nativemodule/core/Android.mk | 2 +- ReactCommon/react/nativemodule/core/BUCK | 1 + .../core/platform/android/ReactCommon/JavaTurboModule.cpp | 3 ++- ReactCommon/react/renderer/textlayoutmanager/Android.mk | 2 +- packages/rn-tester/Podfile.lock | 8 ++++---- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Libraries/NativeAnimation/React-RCTAnimation.podspec b/Libraries/NativeAnimation/React-RCTAnimation.podspec index 547534b755b562..2138829a1de837 100644 --- a/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -39,9 +39,9 @@ Pod::Spec.new do |s| } s.dependency "RCT-Folly", folly_version + s.dependency "FBReactNativeSpec", version s.dependency "RCTTypeSafety", version s.dependency "ReactCommon/turbomodule/core", version s.dependency "React-jsi", version - s.dependency "FBReactNativeSpec", version s.dependency "React-Core/RCTAnimationHeaders", version end diff --git a/ReactCommon/ReactCommon.podspec b/ReactCommon/ReactCommon.podspec index e4b34411605933..f63950228c0cee 100644 --- a/ReactCommon/ReactCommon.podspec +++ b/ReactCommon/ReactCommon.podspec @@ -53,6 +53,10 @@ Pod::Spec.new do |s| "react/nativemodule/core/platform/ios/**/*.{mm,cpp,h}" end + s.subspec "react_debug_core" do |sss| + sss.source_files = "react/debug/*.{cpp,h}" + end + ss.subspec "samples" do |sss| sss.source_files = "react/nativemodule/samples/ReactCommon/**/*.{cpp,h}", "react/nativemodule/samples/platform/ios/**/*.{mm,cpp,h}" diff --git a/ReactCommon/react/debug/Android.mk b/ReactCommon/react/debug/Android.mk index 14bb49bdc87259..669418516b2109 100644 --- a/ReactCommon/react/debug/Android.mk +++ b/ReactCommon/react/debug/Android.mk @@ -24,6 +24,8 @@ LOCAL_CFLAGS := \ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall -llog +LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog + include $(BUILD_SHARED_LIBRARY) $(call import-module,folly) diff --git a/ReactCommon/react/nativemodule/core/Android.mk b/ReactCommon/react/nativemodule/core/Android.mk index 70f7651b4831f4..13339cab74d730 100644 --- a/ReactCommon/react/nativemodule/core/Android.mk +++ b/ReactCommon/react/nativemodule/core/Android.mk @@ -15,7 +15,7 @@ LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/ReactCommon/*.cpp) $(wildcard $(LOCA LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/platform/android/ -LOCAL_SHARED_LIBRARIES := libfbjni libfolly_json libreactnativejni +LOCAL_SHARED_LIBRARIES := libfbjni libfolly_json libreactnativejni libreact_debug LOCAL_STATIC_LIBRARIES := libjsi libreactperflogger diff --git a/ReactCommon/react/nativemodule/core/BUCK b/ReactCommon/react/nativemodule/core/BUCK index 18cc72b93f90af..bf3ae66161b86a 100644 --- a/ReactCommon/react/nativemodule/core/BUCK +++ b/ReactCommon/react/nativemodule/core/BUCK @@ -79,6 +79,7 @@ rn_xplat_cxx_library( react_native_xplat_target("cxxreact:bridge"), react_native_xplat_target("cxxreact:module"), react_native_xplat_target("callinvoker:callinvoker"), + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("reactperflogger:reactperflogger"), ], exported_deps = [ diff --git a/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp b/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp index f00e8bb95e5981..a8bb21897ba3c0 100644 --- a/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp +++ b/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +134,7 @@ std::string stringifyJSIValue(const jsi::Value &v, jsi::Runtime *rt = nullptr) { return "a string (\"" + v.getString(*rt).utf8(*rt) + "\")"; } - assert(v.isObject() && "Expecting object."); + react_native_assert(v.isObject() && "Expecting object."); return rt != nullptr && v.getObject(*rt).isFunction(*rt) ? "a function" : "an object"; } diff --git a/ReactCommon/react/renderer/textlayoutmanager/Android.mk b/ReactCommon/react/renderer/textlayoutmanager/Android.mk index d048ec00061327..fd9e86cdb38b8e 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/Android.mk +++ b/ReactCommon/react/renderer/textlayoutmanager/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_render_textlayoutmanager LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp $(LOCAL_PATH)/platform/android/react/renderer/textlayoutmanager/*.cpp) -LOCAL_SHARED_LIBRARIES := libfolly_futures libreactnativeutilsjni libreact_utils libfb libfbjni libreact_render_uimanager libreact_render_componentregistry libreact_render_attributedstring libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics +LOCAL_SHARED_LIBRARIES := libfolly_futures libreactnativeutilsjni libreact_utils libfb libfbjni libreact_render_uimanager libreact_render_componentregistry libreact_render_attributedstring libfolly_json libyoga libfolly_json libreact_render_core libreact_render_debug libreact_render_graphics libreact_debug LOCAL_STATIC_LIBRARIES := diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index d7d4889b4c7b54..3c56904b3df43a 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -802,7 +802,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 - DoubleConversion: cde416483dac037923206447da6e1454df403714 + DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 FBLazyVector: 91e874a8823933a268c38765a88cbd5dba1fa024 FBReactNativeSpec: 6793f00102a091fb931674853172fb22e5a2c4cf Flipper: d3da1aa199aad94455ae725e9f3aa43f3ec17021 @@ -812,7 +812,7 @@ SPEC CHECKSUMS: Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 Flipper-RSocket: 602921fee03edacf18f5d6f3d3594ba477f456e5 FlipperKit: 8a20b5c5fcf9436cac58551dc049867247f64b00 - glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3 + glog: 5337263514dd6f09803962437687240c5dc39aa4 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b RCT-Folly: ec7a233ccc97cc556cf7237f0db1ff65b986f27c @@ -830,7 +830,7 @@ SPEC CHECKSUMS: React-jsinspector: 52fe8073736a97304c9bc61a5bbae8b66ca55701 React-perflogger: e5c447a0435eb9cdd1e5cd692a48b5c5463406b0 React-RCTActionSheet: 555656ac47e1b81d986a3822e22c374523e0ed17 - React-RCTAnimation: 639d6784188ee28b3cbb5c4915f18fb63b816a46 + React-RCTAnimation: 0bb7a765e92907fb44073438b3a6752ca4ef0df1 React-RCTBlob: b0af8ae625ea63199504c9cfe09151ebeae51884 React-RCTFabric: 447f94b853788b8868157002022bcaa911f2cf00 React-RCTImage: 8626895dc6dabc11f28e3d6a9eb866b2e2c2742d @@ -842,7 +842,7 @@ SPEC CHECKSUMS: React-RCTText: 83931feaad2b470868af24bf7b943cc52a84603d React-RCTVibration: c739e240076fd7dabd90d6242d6a949297565f72 React-runtimeexecutor: d3e89935c7d4733ddf7da3dd8e0b2533adb7bca4 - ReactCommon: 293077fd73008093e681d96ae99e34e56d47160a + ReactCommon: 959d51c4ce5f5885ffd44115a38052dc45b4a489 Yoga: 69c2b21737d8220f647e61141aec8c28f7249ef2 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a From 519418303782349fbd91f2ff110beb24c21da464 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Fri, 26 Feb 2021 21:42:31 -0800 Subject: [PATCH 18/51] Revert D26470604: Bump Android compileSdkVersion and targetSdkVersion to 30 Differential Revision: D26470604 (https://github.com/facebook/react-native/commit/55c8833817c3e9cf9882a712c8b9946a262df231) Original commit changeset: ffd490f6e547 fbshipit-source-id: 71926781696ab7b7fb2b109198a8d02c3286b05f --- .circleci/config.yml | 2 +- ReactAndroid/build.gradle | 2 +- template/android/build.gradle | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9dae8d5352723a..ca3e88fc57bad4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -617,7 +617,7 @@ jobs: environment: - ANDROID_HOME: "C:\\Android\\android-sdk" - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944" - - ANDROID_BUILD_VERSION: 30 + - ANDROID_BUILD_VERSION: 28 - ANDROID_TOOLS_VERSION: 29.0.3 - GRADLE_OPTS: -Dorg.gradle.daemon=false - NDK_VERSION: 20.1.5948944 diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 0944a54a9bab74..8b8a05d29e4738 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -378,7 +378,7 @@ task extractJNIFiles { } android { - compileSdkVersion 30 + compileSdkVersion 29 ndkVersion ANDROID_NDK_VERSION compileOptions { sourceCompatibility(JavaVersion.VERSION_1_8) diff --git a/template/android/build.gradle b/template/android/build.gradle index ac4d64714c0bfb..93232f5fca9389 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -4,8 +4,8 @@ buildscript { ext { buildToolsVersion = "29.0.3" minSdkVersion = 21 - compileSdkVersion = 30 - targetSdkVersion = 30 + compileSdkVersion = 29 + targetSdkVersion = 29 ndkVersion = "20.1.5948944" } repositories { From 01dcec401b903adcb7252cf7c9734cc9631d3bd4 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 19/51] ReactCommon/renderer/components/image: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695038 fbshipit-source-id: afcf2aecad8305b112e1b4ddcc1693380f3defcc --- ReactCommon/react/renderer/components/image/BUCK | 1 + .../react/renderer/components/image/ImageComponentDescriptor.h | 3 ++- ReactCommon/react/renderer/components/image/conversions.h | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ReactCommon/react/renderer/components/image/BUCK b/ReactCommon/react/renderer/components/image/BUCK index f6288911bfe11d..512859a6e39aaa 100644 --- a/ReactCommon/react/renderer/components/image/BUCK +++ b/ReactCommon/react/renderer/components/image/BUCK @@ -50,6 +50,7 @@ rn_xplat_cxx_library( "//xplat/folly:headers_only", "//xplat/folly:molly", YOGA_CXX_TARGET, + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("react/renderer/core:core"), react_native_xplat_target("react/renderer/graphics:graphics"), diff --git a/ReactCommon/react/renderer/components/image/ImageComponentDescriptor.h b/ReactCommon/react/renderer/components/image/ImageComponentDescriptor.h index 1e2b6708649ff2..56bf1f18c35290 100644 --- a/ReactCommon/react/renderer/components/image/ImageComponentDescriptor.h +++ b/ReactCommon/react/renderer/components/image/ImageComponentDescriptor.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -28,7 +29,7 @@ class ImageComponentDescriptor final void adopt(UnsharedShadowNode shadowNode) const override { ConcreteComponentDescriptor::adopt(shadowNode); - assert(std::dynamic_pointer_cast(shadowNode)); + react_native_assert(std::dynamic_pointer_cast(shadowNode)); auto imageShadowNode = std::static_pointer_cast(shadowNode); diff --git a/ReactCommon/react/renderer/components/image/conversions.h b/ReactCommon/react/renderer/components/image/conversions.h index a77d40fad489e1..fa1dd602161e12 100644 --- a/ReactCommon/react/renderer/components/image/conversions.h +++ b/ReactCommon/react/renderer/components/image/conversions.h @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -88,7 +89,7 @@ inline std::string toString(const ImageSource &value) { } inline void fromRawValue(const RawValue &value, ImageResizeMode &result) { - assert(value.hasType()); + react_native_assert(value.hasType()); auto stringValue = (std::string)value; if (stringValue == "cover") { result = ImageResizeMode::Cover; From bdad5f64325c6f7b63e446c14085bc158b8acef8 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 20/51] ReactCommon/renderer/components/modal: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695055 fbshipit-source-id: d70fdda569c09277d511dc154605559ef3cd56e8 --- ReactCommon/react/renderer/components/modal/BUCK | 1 + .../components/modal/ModalHostViewComponentDescriptor.h | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ReactCommon/react/renderer/components/modal/BUCK b/ReactCommon/react/renderer/components/modal/BUCK index 8078dd25c100d0..3eb48ca4cb6cdd 100644 --- a/ReactCommon/react/renderer/components/modal/BUCK +++ b/ReactCommon/react/renderer/components/modal/BUCK @@ -75,6 +75,7 @@ rn_xplat_cxx_library( "//xplat/folly:memory", "//xplat/folly:molly", YOGA_CXX_TARGET, + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("react/renderer/core:core"), react_native_xplat_target("react/renderer/components/image:image"), diff --git a/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h b/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h index e821c911d38879..d9e9fc87796238 100644 --- a/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h +++ b/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include @@ -24,11 +25,12 @@ class ModalHostViewComponentDescriptor final using ConcreteComponentDescriptor::ConcreteComponentDescriptor; void adopt(UnsharedShadowNode shadowNode) const override { - assert(std::dynamic_pointer_cast(shadowNode)); + react_native_assert( + std::dynamic_pointer_cast(shadowNode)); auto modalShadowNode = std::static_pointer_cast(shadowNode); - assert( + react_native_assert( std::dynamic_pointer_cast(modalShadowNode)); auto layoutableShadowNode = std::static_pointer_cast(modalShadowNode); From acb57ff2b631956804ed162e5ade590b8551579c Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 21/51] ReactCommon/renderer/components/picker: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695073 fbshipit-source-id: f59b6ce7d8f2fd2c68bba41070228be981684ce0 --- .../react/renderer/components/picker/iospicker/BUCK | 1 + .../components/picker/iospicker/conversions.h | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ReactCommon/react/renderer/components/picker/iospicker/BUCK b/ReactCommon/react/renderer/components/picker/iospicker/BUCK index 5ae7c2764206cc..cfba993e95315d 100644 --- a/ReactCommon/react/renderer/components/picker/iospicker/BUCK +++ b/ReactCommon/react/renderer/components/picker/iospicker/BUCK @@ -48,6 +48,7 @@ rn_xplat_cxx_library( deps = [ "//xplat/folly:headers_only", YOGA_CXX_TARGET, + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/utils:utils"), react_native_xplat_target("react/renderer/attributedstring:attributedstring"), react_native_xplat_target("react/renderer/core:core"), diff --git a/ReactCommon/react/renderer/components/picker/iospicker/conversions.h b/ReactCommon/react/renderer/components/picker/iospicker/conversions.h index b39f10431b78bc..c2577779cdea82 100644 --- a/ReactCommon/react/renderer/components/picker/iospicker/conversions.h +++ b/ReactCommon/react/renderer/components/picker/iospicker/conversions.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include @@ -17,26 +18,26 @@ namespace react { inline void fromRawValue( const RawValue &value, std::vector &items) { - assert(value.hasType>()); + react_native_assert(value.hasType>()); auto array = (std::vector)value; items.reserve(array.size()); for (auto const &val : array) { bool check = val.hasType>(); - assert(check); + react_native_assert(check); auto map = (better::map)val; PickerItemsStruct item; if (map.find("label") != map.end()) { - assert(map.at("label").hasType()); + react_native_assert(map.at("label").hasType()); item.label = (std::string)map.at("label"); } if (map.find("value") != map.end()) { - assert(map.at("value").hasType()); + react_native_assert(map.at("value").hasType()); item.value = (std::string)map.at("value"); } if (map.find("textColor") != map.end()) { - assert(map.at("textColor").hasType()); + react_native_assert(map.at("textColor").hasType()); item.textColor = (int)map.at("textColor"); } items.push_back(item); From bca02c100873517330b54d6d0e87663cf9bab9f0 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 22/51] ReactCommon/renderer/components/slider: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695097 fbshipit-source-id: 0a861b9f8a435267b16dcb9c37fd501901a544fd --- ReactCommon/react/renderer/components/slider/BUCK | 1 + .../renderer/components/slider/SliderComponentDescriptor.h | 4 +++- .../slider/platform/ios/SliderMeasurementsManager.cpp | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/ReactCommon/react/renderer/components/slider/BUCK b/ReactCommon/react/renderer/components/slider/BUCK index 0b686ba447d76b..412f0443b3e7bc 100644 --- a/ReactCommon/react/renderer/components/slider/BUCK +++ b/ReactCommon/react/renderer/components/slider/BUCK @@ -83,6 +83,7 @@ rn_xplat_cxx_library( "//xplat/folly:headers_only", "//xplat/folly:molly", YOGA_CXX_TARGET, + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("react/renderer/core:core"), react_native_xplat_target("react/renderer/components/image:image"), diff --git a/ReactCommon/react/renderer/components/slider/SliderComponentDescriptor.h b/ReactCommon/react/renderer/components/slider/SliderComponentDescriptor.h index 687ea411a0c06c..8b699249e9f5f1 100644 --- a/ReactCommon/react/renderer/components/slider/SliderComponentDescriptor.h +++ b/ReactCommon/react/renderer/components/slider/SliderComponentDescriptor.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -31,7 +32,8 @@ class SliderComponentDescriptor final void adopt(UnsharedShadowNode shadowNode) const override { ConcreteComponentDescriptor::adopt(shadowNode); - assert(std::dynamic_pointer_cast(shadowNode)); + react_native_assert( + std::dynamic_pointer_cast(shadowNode)); auto sliderShadowNode = std::static_pointer_cast(shadowNode); diff --git a/ReactCommon/react/renderer/components/slider/platform/ios/SliderMeasurementsManager.cpp b/ReactCommon/react/renderer/components/slider/platform/ios/SliderMeasurementsManager.cpp index b7b930825e224d..d23aff739c7aff 100644 --- a/ReactCommon/react/renderer/components/slider/platform/ios/SliderMeasurementsManager.cpp +++ b/ReactCommon/react/renderer/components/slider/platform/ios/SliderMeasurementsManager.cpp @@ -7,13 +7,15 @@ #include "SliderMeasurementsManager.h" +#include + namespace facebook { namespace react { Size SliderMeasurementsManager::measure( SurfaceId surfaceId, LayoutConstraints layoutConstraints) const { - assert(false); // should never reach this point + react_native_assert(false); // should never reach this point return {}; } From 248c2dd7f252947c131d36391d6eea95805dd053 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 23/51] ReactCommon/renderer/components/text: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695125 fbshipit-source-id: 3055dd3db7cd34bba9b3fc141032ac0f663523a1 --- ReactCommon/react/renderer/components/text/BUCK | 1 + .../react/renderer/components/text/ParagraphState.h | 3 ++- .../text/tests/ParagraphLocalDataTest.cpp | 13 ++++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ReactCommon/react/renderer/components/text/BUCK b/ReactCommon/react/renderer/components/text/BUCK index c3616745a1418f..1a38a17d874945 100644 --- a/ReactCommon/react/renderer/components/text/BUCK +++ b/ReactCommon/react/renderer/components/text/BUCK @@ -98,5 +98,6 @@ fb_xplat_cxx_test( ":text", "//xplat/folly:molly", "//xplat/third-party/gmock:gtest", + react_native_xplat_target("react/debug:debug"), ], ) diff --git a/ReactCommon/react/renderer/components/text/ParagraphState.h b/ReactCommon/react/renderer/components/text/ParagraphState.h index 8f320af68e6a1f..bc72ac28c55179 100644 --- a/ReactCommon/react/renderer/components/text/ParagraphState.h +++ b/ReactCommon/react/renderer/components/text/ParagraphState.h @@ -7,6 +7,7 @@ #pragma once +#include #include #include #include @@ -54,7 +55,7 @@ class ParagraphState final { ParagraphState( ParagraphState const &previousState, folly::dynamic const &data) { - assert(false && "Not supported"); + react_native_assert(false && "Not supported"); }; folly::dynamic getDynamic() const; #endif diff --git a/ReactCommon/react/renderer/components/text/tests/ParagraphLocalDataTest.cpp b/ReactCommon/react/renderer/components/text/tests/ParagraphLocalDataTest.cpp index 24e51148450f3c..f38bfe8de4f8e7 100644 --- a/ReactCommon/react/renderer/components/text/tests/ParagraphLocalDataTest.cpp +++ b/ReactCommon/react/renderer/components/text/tests/ParagraphLocalDataTest.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -40,12 +41,14 @@ TEST(ParagraphLocalDataTest, testSomething) { auto result = toDynamic(paragraphState)["attributedString"]; - assert(result["string"] == fragment.string); + react_native_assert(result["string"] == fragment.string); auto textAttribute = result["fragments"][0]["textAttributes"]; - assert(textAttribute["foregroundColor"] == toDynamic(text.foregroundColor)); - assert(textAttribute["opacity"] == text.opacity); - assert(textAttribute["fontStyle"] == toString(*text.fontStyle)); - assert(textAttribute["fontWeight"] == toString(*text.fontWeight)); + react_native_assert( + textAttribute["foregroundColor"] == toDynamic(text.foregroundColor)); + react_native_assert(textAttribute["opacity"] == text.opacity); + react_native_assert(textAttribute["fontStyle"] == toString(*text.fontStyle)); + react_native_assert( + textAttribute["fontWeight"] == toString(*text.fontWeight)); } #endif From 4326cb15274bde7576d8988db4444c0a12dd4978 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 24/51] ReactCommon/renderer/textinput: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695151 fbshipit-source-id: f5447e0a6d2b6bc06ff9456a35386a22106102f8 --- .../textinput/iostextinput/TextInputShadowNode.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputShadowNode.cpp b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputShadowNode.cpp index 4e771d9e5e5780..fb5c0ff7f33bda 100644 --- a/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputShadowNode.cpp +++ b/ReactCommon/react/renderer/components/textinput/iostextinput/TextInputShadowNode.cpp @@ -7,6 +7,7 @@ #include "TextInputShadowNode.h" +#include #include #include #include @@ -82,8 +83,8 @@ void TextInputShadowNode::updateStateIfNeeded( auto reactTreeAttributedString = getAttributedString(layoutContext); auto const &state = getStateData(); - assert(textLayoutManager_); - assert( + react_native_assert(textLayoutManager_); + react_native_assert( (!state.layoutManager || state.layoutManager == textLayoutManager_) && "`StateData` refers to a different `TextLayoutManager`"); From 7f792c8376a53250ee54acb218609db6b5a8a6fb Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 25/51] ReactCommon/renderer/core: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695162 fbshipit-source-id: 5615355f76b9c78d0f8981b3443b7c5900939ede --- ReactCommon/react/renderer/core/BUCK | 1 + ReactCommon/react/renderer/core/Sealable.cpp | 3 ++- ReactCommon/react/renderer/core/Sealable.h | 6 +++++- ReactCommon/react/renderer/core/tests/RawPropsTest.cpp | 3 ++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/ReactCommon/react/renderer/core/BUCK b/ReactCommon/react/renderer/core/BUCK index 63c5767c9ac19b..329b70c69bc609 100644 --- a/ReactCommon/react/renderer/core/BUCK +++ b/ReactCommon/react/renderer/core/BUCK @@ -80,6 +80,7 @@ fb_xplat_cxx_test( deps = [ "//xplat/folly:molly", "//xplat/js/react-native-github/ReactCommon/react/renderer/element:element", + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/renderer/components/view:view"), react_native_xplat_target("react/renderer/components/scrollview:scrollview"), react_native_xplat_target("react/renderer/components/text:text"), diff --git a/ReactCommon/react/renderer/core/Sealable.cpp b/ReactCommon/react/renderer/core/Sealable.cpp index d2e6fc46432233..2326a4ed7b2f70 100644 --- a/ReactCommon/react/renderer/core/Sealable.cpp +++ b/ReactCommon/react/renderer/core/Sealable.cpp @@ -7,6 +7,7 @@ #include "Sealable.h" +#include #include namespace facebook { @@ -24,7 +25,7 @@ namespace react { * http://en.cppreference.com/w/cpp/language/rule_of_three */ -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG Sealable::Sealable() : sealed_(false) {} diff --git a/ReactCommon/react/renderer/core/Sealable.h b/ReactCommon/react/renderer/core/Sealable.h index 2ca6f64aa65025..f57c42eda5ac2b 100644 --- a/ReactCommon/react/renderer/core/Sealable.h +++ b/ReactCommon/react/renderer/core/Sealable.h @@ -9,6 +9,8 @@ #include +#include + namespace facebook { namespace react { @@ -42,8 +44,9 @@ namespace react { * must be prevented. */ -#ifdef NDEBUG +#ifndef REACT_NATIVE_DEBUG +// Release-mode, production version class Sealable { public: inline void seal() const {} @@ -55,6 +58,7 @@ class Sealable { #else +// Debug version class Sealable { public: Sealable(); diff --git a/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp b/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp index 48a8726662b641..7bb589914edd8d 100644 --- a/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp +++ b/ReactCommon/react/renderer/core/tests/RawPropsTest.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -275,7 +276,7 @@ TEST(RawPropsTest, handleRawPropsPrimitiveTypesIncomplete) { EXPECT_EQ((int)*raw.at("intValue", nullptr, nullptr), 42); } -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG TEST(RawPropsTest, handleRawPropsPrimitiveTypesIncorrectLookup) { const auto &raw = RawProps(folly::dynamic::object("intValue", (int)42)); From 768296823d32c841b6d84d919e98002f6c59d77f Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 26/51] ReactCommon/renderer/components/unimplementedview: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695184 fbshipit-source-id: fd98843f3485e13c9650c5a2576a1186ebb121db --- ReactCommon/react/renderer/components/unimplementedview/BUCK | 1 + .../UnimplementedViewComponentDescriptor.cpp | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ReactCommon/react/renderer/components/unimplementedview/BUCK b/ReactCommon/react/renderer/components/unimplementedview/BUCK index cce569f735a355..f7ce99f0223af6 100644 --- a/ReactCommon/react/renderer/components/unimplementedview/BUCK +++ b/ReactCommon/react/renderer/components/unimplementedview/BUCK @@ -53,6 +53,7 @@ rn_xplat_cxx_library( "//xplat/folly:memory", "//xplat/folly:molly", YOGA_CXX_TARGET, + react_native_xplat_target("react/debug:debug"), react_native_xplat_target("react/renderer/debug:debug"), react_native_xplat_target("react/renderer/core:core"), react_native_xplat_target("react/renderer/components/view:view"), diff --git a/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp b/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp index 24946364a4cf1d..56e5d2a6fa13ed 100644 --- a/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp +++ b/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.cpp @@ -7,6 +7,8 @@ #include "UnimplementedViewComponentDescriptor.h" +#include + namespace facebook { namespace react { @@ -25,7 +27,8 @@ Props::Shared UnimplementedViewComponentDescriptor::cloneProps( auto clonedProps = ConcreteComponentDescriptor::cloneProps( props, rawProps); - assert(std::dynamic_pointer_cast(clonedProps)); + react_native_assert( + std::dynamic_pointer_cast(clonedProps)); // We have to clone `Props` object one more time to make sure that we have // an unshared (and non-`const`) copy of it which we can mutate. From c24fc75dce6952ace09753bb00601af0b7abc080 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 27/51] ReactCommon/renderer/components/view: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695203 fbshipit-source-id: df09af5a62044c711368954b5e9b3a114491e2ed --- .../renderer/components/view/YogaLayoutableShadowNode.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp index d30974b4949115..5f17f378a05133 100644 --- a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -6,6 +6,7 @@ */ #include "YogaLayoutableShadowNode.h" +#include #include #include #include @@ -715,7 +716,7 @@ void YogaLayoutableShadowNode::ensureConsistency() const { } void YogaLayoutableShadowNode::ensureYogaChildrenOwnersConsistency() const { -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG // Checking that all Yoga node children have the same `owner`. // The owner might be not equal to the `yogaNode_` though. auto &yogaChildren = yogaNode_.getChildren(); @@ -730,7 +731,7 @@ void YogaLayoutableShadowNode::ensureYogaChildrenOwnersConsistency() const { } void YogaLayoutableShadowNode::ensureYogaChildrenLookFine() const { -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG // Checking that the shapes of Yoga node children object look fine. // This is the only heuristic that might produce false-positive results // (really broken dangled nodes might look fine). This is useful as an early @@ -748,7 +749,7 @@ void YogaLayoutableShadowNode::ensureYogaChildrenLookFine() const { } void YogaLayoutableShadowNode::ensureYogaChildrenAlighment() const { -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG // If the node is not a leaf node, checking that: // - All children are `YogaLayoutableShadowNode` subclasses. // - All Yoga children are owned/connected to corresponding children of From 88088b7851384e85358f5854cf53b6ab3fabbd5b Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 28/51] ReactCommon/renderer/mapbuffer: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695224 fbshipit-source-id: 3044049cb2447a733a9ecae84dcc099b26731acd --- ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp b/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp index 048a4510856bce..5d718d50493b8c 100644 --- a/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp +++ b/ReactCommon/react/renderer/mapbuffer/tests/MapBufferTest.cpp @@ -7,7 +7,6 @@ #include -#include #include #include From da73cca5e22619f858a054719d84a4625e4031ac Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 29/51] ReactCommon/renderer/scheduler: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695253 fbshipit-source-id: b0ff02416ab208dfd71f71c2b3d83009f40be0a9 --- .../react/renderer/scheduler/AsynchronousEventBeat.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp index 2649227d327ffd..4b8cabf43a3305 100644 --- a/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp +++ b/ReactCommon/react/renderer/scheduler/AsynchronousEventBeat.cpp @@ -7,6 +7,8 @@ #include "AsynchronousEventBeat.h" +#include + namespace facebook { namespace react { @@ -23,7 +25,7 @@ AsynchronousEventBeat::AsynchronousEventBeat( void AsynchronousEventBeat::activityDidChange( RunLoopObserver::Delegate const *delegate, RunLoopObserver::Activity activity) const noexcept { - assert(delegate == this); + react_native_assert(delegate == this); induce(); } From 9f120efcf4b294606a24ea3b4828dc2662e9393a Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Fri, 26 Feb 2021 23:26:05 -0800 Subject: [PATCH 30/51] ReactCommon/utils: Migrate uses of NDEBUG to REACT_NATIVE_DEBUG + react_native_assert Summary: For better cross-platform consistency, migrate usages of NDEBUG to REACT_NATIVE_DEBUG. See flags.h for explanation. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D26695275 fbshipit-source-id: 85aae94105a2817d345d25f736386e545dff0a9a --- ReactCommon/react/utils/Android.mk | 6 ++++-- ReactCommon/react/utils/BUCK | 1 + .../utils/CalledOnceMovableOnlyFunction.h | 10 +++++---- ReactCommon/react/utils/ContextContainer.h | 21 ++++++++++++------- .../react/utils/ManagedObjectWrapper.h | 4 +++- ReactCommon/react/utils/RunLoopObserver.cpp | 9 ++++---- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/ReactCommon/react/utils/Android.mk b/ReactCommon/react/utils/Android.mk index 8a8cfca179728a..4e15562a50dcd0 100644 --- a/ReactCommon/react/utils/Android.mk +++ b/ReactCommon/react/utils/Android.mk @@ -11,7 +11,7 @@ LOCAL_MODULE := react_utils LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) -LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_C_INCLUDES := $(LOCAL_PATH) $(LOCAL_PATH)/../../ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../ LOCAL_CFLAGS := \ @@ -20,6 +20,8 @@ LOCAL_CFLAGS := \ LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall LOCAL_STATIC_LIBRARIES := -LOCAL_SHARED_LIBRARIES := +LOCAL_SHARED_LIBRARIES := libreact_debug include $(BUILD_SHARED_LIBRARY) + +$(call import-module,react/debug) diff --git a/ReactCommon/react/utils/BUCK b/ReactCommon/react/utils/BUCK index 2eddc79ce719d2..6e2f7ab2fe9021 100644 --- a/ReactCommon/react/utils/BUCK +++ b/ReactCommon/react/utils/BUCK @@ -59,5 +59,6 @@ rn_xplat_cxx_library( "//xplat/folly:molly", "//xplat/jsi:jsi", react_native_xplat_target("better:better"), + react_native_xplat_target("react/debug:debug"), ], ) diff --git a/ReactCommon/react/utils/CalledOnceMovableOnlyFunction.h b/ReactCommon/react/utils/CalledOnceMovableOnlyFunction.h index b6d31707d139cc..4d4d2c0d056d96 100644 --- a/ReactCommon/react/utils/CalledOnceMovableOnlyFunction.h +++ b/ReactCommon/react/utils/CalledOnceMovableOnlyFunction.h @@ -7,6 +7,8 @@ #include +#include + namespace facebook { namespace react { @@ -31,7 +33,7 @@ class CalledOnceMovableOnlyFunction { } ~CalledOnceMovableOnlyFunction() { - assert( + react_native_assert( (wasCalled_ || wasMovedFrom_) && "`CalledOnceMovableOnlyFunction` is destroyed before being called."); } @@ -57,7 +59,7 @@ class CalledOnceMovableOnlyFunction { CalledOnceMovableOnlyFunction &operator=( CalledOnceMovableOnlyFunction &&other) noexcept { - assert( + react_native_assert( (wasCalled_ || wasMovedFrom_) && "`CalledOnceMovableOnlyFunction` is re-assigned before being called."); wasCalled_ = false; @@ -71,10 +73,10 @@ class CalledOnceMovableOnlyFunction { * Callable. */ ReturnT operator()(ArgumentT... args) { - assert( + react_native_assert( !wasMovedFrom_ && "`CalledOnceMovableOnlyFunction` is called after being moved from."); - assert( + react_native_assert( !wasCalled_ && "`CalledOnceMovableOnlyFunction` is called more than once."); diff --git a/ReactCommon/react/utils/ContextContainer.h b/ReactCommon/react/utils/ContextContainer.h index a8d09655660995..f0e2613fdb9931 100644 --- a/ReactCommon/react/utils/ContextContainer.h +++ b/ReactCommon/react/utils/ContextContainer.h @@ -15,6 +15,9 @@ #include #include +#include +#include + namespace facebook { namespace react { @@ -43,7 +46,7 @@ class ContextContainer final { instances_.insert({key, std::make_shared(instance)}); -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG typeNames_.insert({key, typeid(T).name()}); #endif } @@ -57,7 +60,7 @@ class ContextContainer final { instances_.erase(key); -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG typeNames_.erase(key); #endif } @@ -73,7 +76,7 @@ class ContextContainer final { for (auto const &pair : contextContainer.instances_) { instances_.erase(pair.first); instances_.insert(pair); -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG typeNames_.erase(pair.first); typeNames_.insert( {pair.first, contextContainer.typeNames_.at(pair.first)}); @@ -90,12 +93,14 @@ class ContextContainer final { T at(std::string const &key) const { std::shared_lock lock(mutex_); - assert( + react_native_assert( instances_.find(key) != instances_.end() && "ContextContainer doesn't have an instance for given key."); - assert( +#ifdef REACT_NATIVE_DEBUG + react_native_assert( typeNames_.at(key) == typeid(T).name() && "ContextContainer stores an instance of different type for given key."); +#endif return *std::static_pointer_cast(instances_.at(key)); } @@ -113,9 +118,11 @@ class ContextContainer final { return {}; } - assert( +#ifdef REACT_NATIVE_DEBUG + react_native_assert( typeNames_.at(key) == typeid(T).name() && "ContextContainer stores an instance of different type for given key."); +#endif return *std::static_pointer_cast(iterator->second); } @@ -124,7 +131,7 @@ class ContextContainer final { mutable better::shared_mutex mutex_; // Protected by mutex_`. mutable better::map> instances_; -#ifndef NDEBUG +#ifdef REACT_NATIVE_DEBUG mutable better::map typeNames_; #endif }; diff --git a/ReactCommon/react/utils/ManagedObjectWrapper.h b/ReactCommon/react/utils/ManagedObjectWrapper.h index 623158015740d5..f91cd3e99d81d2 100644 --- a/ReactCommon/react/utils/ManagedObjectWrapper.h +++ b/ReactCommon/react/utils/ManagedObjectWrapper.h @@ -7,6 +7,8 @@ #pragma once +#include + #if defined(__OBJC__) && defined(__cplusplus) #if TARGET_OS_MAC && TARGET_OS_IPHONE @@ -65,7 +67,7 @@ inline std::shared_ptr wrapManagedObjectWeakly(id object) noexcept inline id unwrapManagedObjectWeakly(std::shared_ptr const &object) noexcept { RCTInternalGenericWeakWrapper *weakWrapper = (RCTInternalGenericWeakWrapper *)unwrapManagedObject(object); - assert(weakWrapper && "`RCTInternalGenericWeakWrapper` instance must not be `nil`."); + react_native_assert(weakWrapper && "`RCTInternalGenericWeakWrapper` instance must not be `nil`."); return weakWrapper.object; } diff --git a/ReactCommon/react/utils/RunLoopObserver.cpp b/ReactCommon/react/utils/RunLoopObserver.cpp index bca81b6664d7b5..d24c3ede72bb13 100644 --- a/ReactCommon/react/utils/RunLoopObserver.cpp +++ b/ReactCommon/react/utils/RunLoopObserver.cpp @@ -7,7 +7,7 @@ #include "RunLoopObserver.h" -#include +#include namespace facebook { namespace react { @@ -19,8 +19,9 @@ RunLoopObserver::RunLoopObserver( void RunLoopObserver::setDelegate(Delegate const *delegate) const noexcept { // We need these constraints to ensure basic thread-safety. - assert(delegate && "A delegate must not be `nullptr`."); - assert(!delegate_ && "`RunLoopObserver::setDelegate` must be called once."); + react_native_assert(delegate && "A delegate must not be `nullptr`."); + react_native_assert( + !delegate_ && "`RunLoopObserver::setDelegate` must be called once."); delegate_ = delegate; } @@ -47,7 +48,7 @@ void RunLoopObserver::activityDidChange(Activity activity) const noexcept { return; } - assert( + react_native_assert( !owner_.expired() && "`owner_` is null. The caller must `lock` the owner and check it for being not null."); From f7d006e60c5ee4888d1fb7142da18554e81b5cbf Mon Sep 17 00:00:00 2001 From: Samuel Susla Date: Sat, 27 Feb 2021 04:53:03 -0800 Subject: [PATCH 31/51] Fix memory leak convertJSIFunctionToCallback Summary: changelog: [internal] ### When does leak happen? Leak happens anytime a callback isn't executed inside native module, it will never get cleaned up. Imagine a native module with method that takes onSuccess and onFail callbacks. Only one of them will be called at any time and the other one will leak. ### Why does it leak? It leaks because when `CallbackWrapper` is created using `CallbackWrapper::createWeak`. Inside `CallbackWrapper::createWeak`, the newly created object is inserted into `LongLivedObjectCollection`. This object collection will keep it alive until `CallbackWrapper::destroy` is called, which isn't called in case closure isn't executed. ### Solution Introduce class RCTBlockGuard which ties cleanup of resources to lifetime of the block. Reviewed By: RSNara Differential Revision: D26664173 fbshipit-source-id: 9348f7c39eb317cf1e8e5d59e77a378e5e04f3eb --- React/Base/RCTBridge.h | 4 +++ React/Base/RCTBridge.m | 11 ++++++++ .../core/platform/ios/RCTBlockGuard.h | 24 ++++++++++++++++ .../core/platform/ios/RCTBlockGuard.mm | 28 +++++++++++++++++++ .../core/platform/ios/RCTTurboModule.mm | 16 ++++++++++- 5 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.h create mode 100644 ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.mm diff --git a/React/Base/RCTBridge.h b/React/Base/RCTBridge.h index 36678d39629e4e..87c1a616bd13e1 100644 --- a/React/Base/RCTBridge.h +++ b/React/Base/RCTBridge.h @@ -160,6 +160,10 @@ RCT_EXTERN void RCTEnableTurboModuleEagerInit(BOOL enabled); RCT_EXTERN BOOL RCTTurboModuleSharedMutexInitEnabled(void); RCT_EXTERN void RCTEnableTurboModuleSharedMutexInit(BOOL enabled); +// Turn on TurboModule shared mutex initialization +RCT_EXTERN BOOL RCTTurboModuleBlockGuardEnabled(void); +RCT_EXTERN void RCTEnableTurboModuleBlockGuard(BOOL enabled); + /** * Async batched bridge used to communicate with the JavaScript application. */ diff --git a/React/Base/RCTBridge.m b/React/Base/RCTBridge.m index cee883f875d980..ee31c54c379256 100644 --- a/React/Base/RCTBridge.m +++ b/React/Base/RCTBridge.m @@ -135,6 +135,17 @@ void RCTEnableTurboModuleSharedMutexInit(BOOL enabled) turboModuleSharedMutexInitEnabled = enabled; } +static BOOL turboModuleBlockGuardEnabled = NO; +BOOL RCTTurboModuleBlockGuardEnabled(void) +{ + return turboModuleBlockGuardEnabled; +} + +void RCTEnableTurboModuleBlockGuard(BOOL enabled) +{ + turboModuleBlockGuardEnabled = enabled; +} + @interface RCTBridge () @end diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.h b/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.h new file mode 100644 index 00000000000000..38dbd2bee4b7f3 --- /dev/null +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * RCTBlockGuard is designed to be used with obj-c blocks to assist with manual deallocation of C++ resources + * tied to lifetime of a block. If C++ resources needs to be manually released at the end of block or when the block + * is deallocated, place the clean up code inside constructor and make sure the instace of the class is references in + * the block. + */ +@interface RCTBlockGuard : NSObject + +- (instancetype)initWithCleanup:(void (^)(void))cleanup; + +@end + +NS_ASSUME_NONNULL_END diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.mm b/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.mm new file mode 100644 index 00000000000000..54a856a25a768a --- /dev/null +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTBlockGuard.mm @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "RCTBlockGuard.h" + +@implementation RCTBlockGuard { + void (^_cleanup)(void); +} + +- (instancetype)initWithCleanup:(void (^)(void))cleanup +{ + if (self = [super init]) { + _cleanup = cleanup; + } + + return self; +} + +- (void)dealloc +{ + _cleanup(); +} + +@end diff --git a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm index de1bed23f8ea50..b730492b9033d8 100644 --- a/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm +++ b/ReactCommon/react/nativemodule/core/platform/ios/RCTTurboModule.mm @@ -6,6 +6,7 @@ */ #import "RCTTurboModule.h" +#import "RCTBlockGuard.h" #import #import @@ -170,6 +171,16 @@ static int32_t getUniqueId() convertJSIFunctionToCallback(jsi::Runtime &runtime, const jsi::Function &value, std::shared_ptr jsInvoker) { auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker); + RCTBlockGuard *blockGuard; + if (RCTTurboModuleBlockGuardEnabled()) { + blockGuard = [[RCTBlockGuard alloc] initWithCleanup:^() { + auto strongWrapper = weakWrapper.lock(); + if (strongWrapper) { + strongWrapper->destroy(); + } + }]; + } + BOOL __block wrapperWasCalled = NO; RCTResponseSenderBlock callback = ^(NSArray *responses) { if (wrapperWasCalled) { @@ -181,7 +192,7 @@ static int32_t getUniqueId() return; } - strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses]() { + strongWrapper->jsInvoker().invokeAsync([weakWrapper, responses, blockGuard]() { auto strongWrapper2 = weakWrapper.lock(); if (!strongWrapper2) { return; @@ -190,6 +201,9 @@ static int32_t getUniqueId() std::vector args = convertNSArrayToStdVector(strongWrapper2->runtime(), responses); strongWrapper2->callback().call(strongWrapper2->runtime(), (const jsi::Value *)args.data(), args.size()); strongWrapper2->destroy(); + + // Delete the CallbackWrapper when the block gets dealloced without being invoked. + (void)blockGuard; }); wrapperWasCalled = YES; From 5f1012c6f2cea5c1ed8cd07728ab4aa4891b4272 Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 28 Feb 2021 08:43:48 -0800 Subject: [PATCH 32/51] Back out "Fix incorrect Height in Text components" Summary: Original commit changeset: 3e769e0ca35b Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D26696638 fbshipit-source-id: 1dd432b35505be8e1b437a4578342cf84a6a5134 --- .../react/renderer/textlayoutmanager/TextMeasureCache.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h index 823d106a3191d8..d0e71872810d75 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h +++ b/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h @@ -190,9 +190,7 @@ inline bool operator==( lhs.attributedString, rhs.attributedString) && lhs.paragraphAttributes == rhs.paragraphAttributes && lhs.layoutConstraints.maximumSize.width == - rhs.layoutConstraints.maximumSize.width && - lhs.layoutConstraints.maximumSize.height == - rhs.layoutConstraints.maximumSize.height; + rhs.layoutConstraints.maximumSize.width; } inline bool operator!=( From f27621465d82f2b75676c1f745c82e814452602d Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Sun, 28 Feb 2021 08:43:48 -0800 Subject: [PATCH 33/51] Fabric: Fixes in Android TextLayoutManager for better caching performance Summary: The is how it works: * Text is a quite special component with special properties and constraints. Some of them are: It's expensive to measure (layout) text. It's expensive to measure and expensive to pass AttributedString via JNI. * When we measure text, we don't concerned about maximum height, only maximum height is important. (Even though theoretically, there are text layout systems that can balance these constraints (max height and width) trying to find a perfect result, we don't use such complex (and expensive) layout engines for building UIs). Yoga, as a flexbox engine, does not aware of such constraints, so it requests remeasuring of text components quite often, so we have an RN built-in text measure cache system just for text measurements that suit these constraints. This way when Yoga requests a text measuring, we always measure with `Inf` height and store that result in the cache. And when Yoga requests another measure with the same width but a different height we retrieve the value from the cache and then just clamp it. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D26696637 fbshipit-source-id: f65b275d33c77073bc2359cbf0a741ddcf05d8d4 --- .../renderer/textlayoutmanager/TextLayoutManager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp b/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp index 83f8c930311316..a9e486219a3558 100644 --- a/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp +++ b/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.cpp @@ -7,6 +7,8 @@ #include "TextLayoutManager.h" +#include + #include #include #include @@ -29,12 +31,15 @@ TextMeasurement TextLayoutManager::measure( LayoutConstraints layoutConstraints) const { auto &attributedString = attributedStringBox.getValue(); - return measureCache_.get( + auto measurement = measureCache_.get( {attributedString, paragraphAttributes, layoutConstraints}, [&](TextMeasureCacheKey const &key) { return doMeasure( attributedString, paragraphAttributes, layoutConstraints); }); + + measurement.size = layoutConstraints.clamp(measurement.size); + return measurement; } TextMeasurement TextLayoutManager::measureCachedSpannableById( @@ -126,6 +131,8 @@ TextMeasurement TextLayoutManager::doMeasure( AttributedString attributedString, ParagraphAttributes paragraphAttributes, LayoutConstraints layoutConstraints) const { + layoutConstraints.maximumSize.height = std::numeric_limits::infinity(); + int attachmentsCount = 0; for (auto fragment : attributedString.getFragments()) { if (fragment.isAttachment()) { From 69feed518d01a7d91f0c71509429c4388912131c Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Sun, 28 Feb 2021 15:16:14 -0800 Subject: [PATCH 34/51] Send UNIX timestamp along with JS touch events, instead of systemUptime Summary: We want to be able to instrument touch processing delays in JS, which does not have access to systemUptime; therefore we want a UNIX timestamp, which JS has access to and can compare to the touch time. It only matters that there is relative consistency between multiple touch events in JS, which is still the case; so this should have no impact on product code. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D26705429 fbshipit-source-id: 0f2db726048fcab9a30e830970d7d8a8d2eae446 --- .../facebook/react/uimanager/events/Event.java | 18 +++++++++++++++++- .../react/uimanager/events/TouchesHelper.java | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java index bd3b06b16e6de1..e8976cce961970 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/Event.java @@ -38,6 +38,15 @@ public abstract class Event { private long mTimestampMs; private int mUniqueID = sUniqueID++; + // Android native Event times use 'uptimeMillis', and historically we've used `uptimeMillis` + // throughout this Event class as the coalescing key for events, and for other purposes. + // To get an accurate(ish) absolute UNIX time for the event, we store the initial clock time here. + // uptimeMillis can then be added to this to get an accurate UNIX time. + // However, we still default to uptimeMillis: you must explicitly request UNIX time if you want + // that; see `getUnixTimestampMs`. + public static final long sInitialClockTimeUnixOffset = + SystemClock.currentTimeMillis() - SystemClock.uptimeMillis(); + protected Event() {} @Deprecated @@ -58,8 +67,10 @@ protected void init(int viewTag) { protected void init(int surfaceId, int viewTag) { mSurfaceId = surfaceId; mViewTag = viewTag; - mTimestampMs = SystemClock.uptimeMillis(); mInitialized = true; + + // This is a *relative* time. See `getUnixTimestampMs`. + mTimestampMs = SystemClock.uptimeMillis(); } /** @return the view id for the view that generated this event */ @@ -80,6 +91,11 @@ public final long getTimestampMs() { return mTimestampMs; } + /** @return the time at which the event happened as a UNIX timestamp, in milliseconds. */ + public final long getUnixTimestampMs() { + return sInitialClockTimeUnixOffset + mTimestampMs; + } + /** @return false if this Event can *never* be coalesced */ public boolean canCoalesce() { return true; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java index 187e61211604c2..b67f6e3eff06ef 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/TouchesHelper.java @@ -64,7 +64,7 @@ private static WritableArray createsPointersArray( touch.putDouble(LOCATION_Y_KEY, PixelUtil.toDIPFromPixel(locationY)); touch.putInt(TARGET_SURFACE_KEY, surfaceId); touch.putInt(TARGET_KEY, reactTarget); - touch.putDouble(TIMESTAMP_KEY, event.getTimestampMs()); + touch.putDouble(TIMESTAMP_KEY, event.getUnixTimestampMs()); touch.putDouble(POINTER_IDENTIFIER_KEY, motionEvent.getPointerId(index)); touches.pushMap(touch); } From b08362ade5d68af4b6c66d5cf0dab5f42a2ec894 Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Sun, 28 Feb 2021 15:16:14 -0800 Subject: [PATCH 35/51] Send unix timestamp for touch events instead of systemUptime Summary: We want to be able to instrument touch processing delays in JS, which does not have access to systemUptime; therefore we want a UNIX timestamp, which JS has access to and can compare to the touch time. It only matters that there is relative consistency between multiple touch events in JS, which is still the case; so this should have no impact on product code. Changelog: [Internal] Reviewed By: sammy-SC Differential Revision: D26705430 fbshipit-source-id: 2acd52ae5873a44edf1e0cb126a9a6c87203d8fa --- React/Base/RCTTouchHandler.m | 10 +++++- React/Fabric/RCTSurfaceTouchHandler.mm | 26 +++++++++++---- .../react/renderer/components/view/Touch.h | 33 ++++++++++++++++++- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/React/Base/RCTTouchHandler.m b/React/Base/RCTTouchHandler.m index fc32afb0a79cfc..bfcadc3d607335 100644 --- a/React/Base/RCTTouchHandler.m +++ b/React/Base/RCTTouchHandler.m @@ -8,6 +8,7 @@ #import "RCTTouchHandler.h" #import +#import #import "RCTAssert.h" #import "RCTBridge.h" @@ -39,6 +40,10 @@ @implementation RCTTouchHandler { __weak UIView *_cachedRootView; + // See Touch.h and usage. This gives us a time-basis for a monotonic + // clock that acts like a timestamp of milliseconds elapsed since UNIX epoch. + NSTimeInterval _unixEpochBasisTime; + uint16_t _coalescingKey; } @@ -53,6 +58,9 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge _reactTouches = [NSMutableArray new]; _touchViews = [NSMutableArray new]; + // Get a UNIX epoch basis time: + _unixEpochBasisTime = [[NSDate date] timeIntervalSince1970] - [NSProcessInfo processInfo].systemUptime; + // `cancelsTouchesInView` and `delaysTouches*` are needed in order to be used as a top level // event delegated recognizer. Otherwise, lower-level components not built // using RCT, will fail to recognize gestures. @@ -159,7 +167,7 @@ - (void)_updateReactTouchAtIndex:(NSInteger)touchIndex reactTouch[@"pageY"] = @(RCTSanitizeNaNValue(rootViewLocation.y, @"touchEvent.pageY")); reactTouch[@"locationX"] = @(RCTSanitizeNaNValue(touchViewLocation.x, @"touchEvent.locationX")); reactTouch[@"locationY"] = @(RCTSanitizeNaNValue(touchViewLocation.y, @"touchEvent.locationY")); - reactTouch[@"timestamp"] = @(nativeTouch.timestamp * 1000); // in ms, for JS + reactTouch[@"timestamp"] = @((_unixEpochBasisTime + nativeTouch.timestamp) * 1000); // in ms, for JS // TODO: force for a 'normal' touch is usually 1.0; // should we expose a `normalTouchForce` constant somewhere (which would diff --git a/React/Fabric/RCTSurfaceTouchHandler.mm b/React/Fabric/RCTSurfaceTouchHandler.mm index eb5d126eda3370..ba64bef7c1c786 100644 --- a/React/Fabric/RCTSurfaceTouchHandler.mm +++ b/React/Fabric/RCTSurfaceTouchHandler.mm @@ -10,6 +10,7 @@ #import #import #import +#import #import "RCTConversions.h" #import "RCTTouchableComponentViewProtocol.h" @@ -82,7 +83,8 @@ static void UpdateActiveTouchWithUITouch( ActiveTouch &activeTouch, UITouch *uiTouch, UIView *rootComponentView, - CGPoint rootViewOriginOffset) + CGPoint rootViewOriginOffset, + NSTimeInterval unixTimestampBasis) { CGPoint offsetPoint = [uiTouch locationInView:activeTouch.componentView]; CGPoint screenPoint = [uiTouch locationInView:uiTouch.window]; @@ -93,14 +95,18 @@ static void UpdateActiveTouchWithUITouch( activeTouch.touch.screenPoint = RCTPointFromCGPoint(screenPoint); activeTouch.touch.pagePoint = RCTPointFromCGPoint(pagePoint); - activeTouch.touch.timestamp = uiTouch.timestamp; + activeTouch.touch.timestamp = unixTimestampBasis + uiTouch.timestamp; if (RCTForceTouchAvailable()) { activeTouch.touch.force = RCTZeroIfNaN(uiTouch.force / uiTouch.maximumPossibleForce); } } -static ActiveTouch CreateTouchWithUITouch(UITouch *uiTouch, UIView *rootComponentView, CGPoint rootViewOriginOffset) +static ActiveTouch CreateTouchWithUITouch( + UITouch *uiTouch, + UIView *rootComponentView, + CGPoint rootViewOriginOffset, + NSTimeInterval unixTimestampBasis) { ActiveTouch activeTouch = {}; @@ -117,7 +123,7 @@ static ActiveTouch CreateTouchWithUITouch(UITouch *uiTouch, UIView *rootComponen componentView = componentView.superview; } - UpdateActiveTouchWithUITouch(activeTouch, uiTouch, rootComponentView, rootViewOriginOffset); + UpdateActiveTouchWithUITouch(activeTouch, uiTouch, rootComponentView, rootViewOriginOffset, unixTimestampBasis); return activeTouch; } @@ -167,6 +173,12 @@ @implementation RCTSurfaceTouchHandler { */ __weak UIView *_rootComponentView; IdentifierPool<11> _identifierPool; + + /* + * See Touch.h and usage. This gives us a time-basis for a monotonic + * clock that acts like a timestamp of milliseconds elapsed since UNIX epoch. + */ + NSTimeInterval _unixEpochBasisTime; } - (instancetype)init @@ -181,6 +193,8 @@ - (instancetype)init self.delaysTouchesEnded = NO; self.delegate = self; + + _unixEpochBasisTime = [[NSDate date] timeIntervalSince1970] - [NSProcessInfo processInfo].systemUptime; } return self; @@ -208,7 +222,7 @@ - (void)detachFromView:(UIView *)view - (void)_registerTouches:(NSSet *)touches { for (UITouch *touch in touches) { - auto activeTouch = CreateTouchWithUITouch(touch, _rootComponentView, _viewOriginOffset); + auto activeTouch = CreateTouchWithUITouch(touch, _rootComponentView, _viewOriginOffset, _unixEpochBasisTime); activeTouch.touch.identifier = _identifierPool.dequeue(); _activeTouches.emplace(touch, activeTouch); } @@ -223,7 +237,7 @@ - (void)_updateTouches:(NSSet *)touches continue; } - UpdateActiveTouchWithUITouch(iterator->second, touch, _rootComponentView, _viewOriginOffset); + UpdateActiveTouchWithUITouch(iterator->second, touch, _rootComponentView, _viewOriginOffset, _unixEpochBasisTime); } } diff --git a/ReactCommon/react/renderer/components/view/Touch.h b/ReactCommon/react/renderer/components/view/Touch.h index 91b6db7522b552..5a150b955e321d 100644 --- a/ReactCommon/react/renderer/components/view/Touch.h +++ b/ReactCommon/react/renderer/components/view/Touch.h @@ -52,7 +52,38 @@ struct Touch { Float force; /* - * The time in seconds when the touch occurred or when it was last mutated. + * The time in seconds (with fractional milliseconds) when the touch occurred + * or when it was last mutated. + * + * Whenever possible this should be computed as: + * 1. Pick MONO_CLOCK_NOW, a monotonic system clock. Generally, something like + * `systemUptimeMillis`. + * 2. BASIS_TIME = unix timestamp from unix epoch (ms) - MONO_CLOCK_NOW + * 3. Then assign timestamp = BASIS_TIME + MONO_CLOCK_NOW + * + * The effect should be UNIX timestamp from UNIX epoch, but as a monotonic + * clock (if you just assign to current system time, it can move backwards due + * to clock adjustements, leap seconds, etc etc). So the vast majority of the + * time it will look identical to current UNIX time, but there are some + * edge-cases where it can drift. + * + * If you are not able to use the scheme above for some reason, prefer to use + * a monotonic clock. This timestamp MUST be monotonic. Do NOT just pass along + * system time. + * + * The goal is to allow touch latency to be computed in JS. JS does not have + * access to something like `systemUptimeMillis`, it generally can only access + * the current system time. This *does* mean that the touch latency could be + * computed incorrectly in cases of clock drift, so you should only use this + * as telemetry to get a decent, but not totally perfect, idea of performance. + * Do not use this latency information for anything "mission critical". You + * can assume it's probably reasonably accurate 99% of the time. + * + * Note that we attempt to adhere to the spec of timestamp here: + * https://dom.spec.whatwg.org/#dom-event-timestamp + * Notably, since `global` is not a Window object in React Native, we have + * some flexibility in how we define the time origin: + * https://w3c.github.io/hr-time/#dfn-time-origin */ Float timestamp; From 21a434ceec97681574aeedf5e8340f2c58f6f80e Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Mon, 1 Mar 2021 15:46:07 -0800 Subject: [PATCH 36/51] Fix crash associated with setJSResponderHandler Summary: In Fabric we're seeing setJSResponderHandler called during teardown of a surface, which causes a crash because the SurfaceId is no longer available at that point. Guard against setJSResponderHandler being called on a dead surface. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26734786 fbshipit-source-id: 838d682ee0dd1d4de49993fa479dc2097cf33521 --- .../react/fabric/FabricUIManager.java | 11 +++++-- .../fabric/mounting/MountingManager.java | 29 ++----------------- .../mountitems/PreAllocateViewMountItem.java | 13 +++++++-- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index ae5a01fcf68fad..11dfbf9c7e8337 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -1079,8 +1079,15 @@ public void setJSResponder( new MountItem() { @Override public void execute(MountingManager mountingManager) { - mountingManager.setJSResponder( - surfaceId, reactTag, initialReactTag, blockNativeResponder); + SurfaceMountingManager surfaceMountingManager = + mountingManager.getSurfaceManager(surfaceId); + if (surfaceMountingManager != null) { + surfaceMountingManager.setJSResponder( + reactTag, initialReactTag, blockNativeResponder); + } else { + FLog.e( + TAG, "setJSResponder skipped, surface no longer available [" + surfaceId + "]"); + } } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index b916ff6ffd3bc6..a45742450dc8b8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -270,38 +270,15 @@ public void updateProps(int reactTag, @Nullable ReadableMap props) { getSurfaceManagerForViewEnforced(reactTag).updateProps(reactTag, props); } - /** - * Set the JS responder for the view associated with the tags received as a parameter. - * - *

The JSResponder coordinates the return values of the onInterceptTouch method in Android - * Views. This allows JS to coordinate when a touch should be handled by JS or by the Android - * native views. See {@link JSResponderHandler} for more details. - * - *

This method is going to be executed on the UIThread as soon as it is delivered from JS to - * RN. - * - *

Currently, there is no warranty that the view associated with the react tag exists, because - * this method is not handled by the react commit process. - * - * @param reactTag React tag of the first parent of the view that is NOT virtual - * @param initialReactTag React tag of the JS view that initiated the touch operation - * @param blockNativeResponder If native responder should be blocked or not - */ - @UiThread - public synchronized void setJSResponder( - int surfaceId, int reactTag, int initialReactTag, boolean blockNativeResponder) { - UiThreadUtil.assertOnUiThread(); - - getSurfaceManagerEnforced(surfaceId, "setJSResponder") - .setJSResponder(reactTag, initialReactTag, blockNativeResponder); - } - /** * Clears the JS Responder specified by {@link #setJSResponder(int, int, int, boolean)}. After * this method is called, all the touch events are going to be handled by JS. */ @UiThread public void clearJSResponder() { + // MountingManager and SurfaceMountingManagers all share the same JSResponderHandler. + // Must be called on MountingManager instead of SurfaceMountingManager, because we don't + // know what surfaceId it's being called for. mJSResponderHandler.clearJSResponder(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java index 7764bd58a3c452..7b540ae89a42d3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java @@ -16,6 +16,7 @@ import com.facebook.common.logging.FLog; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.fabric.mounting.MountingManager; +import com.facebook.react.fabric.mounting.SurfaceMountingManager; import com.facebook.react.uimanager.StateWrapper; /** {@link MountItem} that is used to pre-allocate views for JS components. */ @@ -53,9 +54,15 @@ public void execute(@NonNull MountingManager mountingManager) { if (ENABLE_FABRIC_LOGS) { FLog.d(TAG, "Executing pre-allocation of: " + toString()); } - mountingManager - .getSurfaceManagerEnforced(mSurfaceId, "PreAllocateViewMountItem") - .preallocateView(mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable); + SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId); + if (surfaceMountingManager == null) { + FLog.e( + TAG, + "Skipping View PreAllocation; no SurfaceMountingManager found for [" + mSurfaceId + "]"); + return; + } + surfaceMountingManager.preallocateView( + mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable); } @Override From 05f687fa88e29554c8da99bba33b07aac83a3a5c Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 1 Mar 2021 17:52:20 -0800 Subject: [PATCH 37/51] Extract getViewportOffset out RootView Summary: This diff moves the method getViewportOffset out of ReactRootView. This is necessary to avoid Fabric to depend from paper. changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26716901 fbshipit-source-id: cec67c24860a776fb361d7cda08d3142e1214c8c --- .../src/main/java/com/facebook/react/BUCK | 1 + .../com/facebook/react/ReactRootView.java | 19 ++----------------- .../main/java/com/facebook/react/fabric/BUCK | 1 - .../com/facebook/react/fabric/Binding.java | 1 + .../react/fabric/FabricUIManager.java | 4 ++-- .../react/uimanager/RootViewUtil.java | 18 ++++++++++++++++++ 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index 6f76ec6ff501fc..6019f3f39f8ac7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -30,6 +30,7 @@ rn_android_library( react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/devsupport:devsupport"), react_native_target("java/com/facebook/react/devsupport:interfaces"), + react_native_target("java/com/facebook/react/fabric:fabric"), react_native_target("java/com/facebook/react/jscexecutor:jscexecutor"), react_native_target("java/com/facebook/react/jstasks:jstasks"), react_native_target("java/com/facebook/react/module/annotations:annotations"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 610dd67bde537f..1efc5fe0890ca3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -27,7 +27,6 @@ import android.view.WindowManager; import android.widget.FrameLayout; import androidx.annotation.Nullable; -import androidx.annotation.UiThread; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.ThreadConfined; @@ -52,6 +51,7 @@ import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactRoot; import com.facebook.react.uimanager.RootView; +import com.facebook.react.uimanager.RootViewUtil; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.events.EventDispatcher; @@ -420,21 +420,6 @@ public AtomicInteger getState() { return mState; } - @UiThread - public static Point getViewportOffset(View v) { - int[] locationInWindow = new int[2]; - v.getLocationInWindow(locationInWindow); - - // we need to subtract visibleWindowCoords - to subtract possible window insets, split - // screen or multi window - Rect visibleWindowFrame = new Rect(); - v.getWindowVisibleDisplayFrame(visibleWindowFrame); - locationInWindow[0] -= visibleWindowFrame.left; - locationInWindow[1] -= visibleWindowFrame.top; - - return new Point(locationInWindow[0], locationInWindow[1]); - } - /** * Call whenever measure specs change, or if you want to force an update of offsetX/offsetY. If * measureSpecsChanged is false and the offsetX/offsetY don't change, updateRootLayoutSpecs will @@ -472,7 +457,7 @@ private void updateRootLayoutSpecs( int offsetX = 0; int offsetY = 0; if (getUIManagerType() == FABRIC) { - Point viewportOffset = getViewportOffset(this); + Point viewportOffset = RootViewUtil.getViewportOffset(this); offsetX = viewportOffset.x; offsetY = viewportOffset.y; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK index f3cb842381849b..12ad6392e594d6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK @@ -33,7 +33,6 @@ rn_android_library( react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/config:config"), react_native_target("java/com/facebook/react/fabric/jni:jni"), - react_native_target("java/com/facebook/react:react"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/modules/core:core"), react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java index 61296c84a70cbb..9020ab17e775f7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java @@ -91,6 +91,7 @@ public void register( jsMessageQueueThread, componentFactory, reactNativeConfig); + setPixelDensity(PixelUtil.getDisplayMetricDensity()); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 11dfbf9c7e8337..08cd93b133e9f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -35,7 +35,6 @@ import com.facebook.debug.tags.ReactDebugOverlayTags; import com.facebook.infer.annotation.ThreadConfined; import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.ReactRootView; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeMap; @@ -73,6 +72,7 @@ import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactRoot; import com.facebook.react.uimanager.ReactRootViewTagGenerator; +import com.facebook.react.uimanager.RootViewUtil; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; @@ -252,7 +252,7 @@ public int startSurface( // ViewportOffset during measurement or onLayout. @SuppressLint("WrongThread") Point viewportOffset = - UiThreadUtil.isOnUiThread() ? ReactRootView.getViewportOffset(rootView) : new Point(0, 0); + UiThreadUtil.isOnUiThread() ? RootViewUtil.getViewportOffset(rootView) : new Point(0, 0); mBinding.startSurfaceWithConstraints( rootTag, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java index 41bae5be249ae2..2c2e35460b8074 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java @@ -7,8 +7,11 @@ package com.facebook.react.uimanager; +import android.graphics.Point; +import android.graphics.Rect; import android.view.View; import android.view.ViewParent; +import androidx.annotation.UiThread; import com.facebook.infer.annotation.Assertions; public class RootViewUtil { @@ -28,4 +31,19 @@ public static RootView getRootView(View reactView) { current = (View) next; } } + + @UiThread + public static Point getViewportOffset(View v) { + int[] locationInWindow = new int[2]; + v.getLocationInWindow(locationInWindow); + + // we need to subtract visibleWindowCoords - to subtract possible window insets, split + // screen or multi window + Rect visibleWindowFrame = new Rect(); + v.getWindowVisibleDisplayFrame(visibleWindowFrame); + locationInWindow[0] -= visibleWindowFrame.left; + locationInWindow[1] -= visibleWindowFrame.top; + + return new Point(locationInWindow[0], locationInWindow[1]); + } } From 71ccc61802397a087635e8bfff9d57d9f586dc13 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 1 Mar 2021 17:52:20 -0800 Subject: [PATCH 38/51] Refactor ReactInstanceManager.getViewManagerNames Summary: This diff refactors the ReactInstanceManager.getViewManagerNames method to cache viewManager names changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26716898 fbshipit-source-id: 93985fe248e7b364081e04dd2b2c6d9b46cb8727 --- .../facebook/react/ReactInstanceManager.java | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 056880805cec10..cca71a2dccf28c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -153,6 +153,7 @@ public interface ReactInstanceEventListener { /* accessed from any thread */ private final JavaScriptExecutorFactory mJavaScriptExecutorFactory; + private @Nullable List mViewManagerNames = null; private final @Nullable JSBundleLoader mBundleLoader; private final @Nullable String mJSMainModulePath; /* path to JS bundle root on Metro */ private final List mPackages; @@ -711,6 +712,9 @@ public void destroy() { synchronized (mHasStartedDestroying) { mHasStartedDestroying.notifyAll(); } + synchronized (mPackages) { + mViewManagerNames = null; + } FLog.d(ReactConstants.TAG, "ReactInstanceManager has been destroyed"); } @@ -908,33 +912,38 @@ public List getOrCreateViewManagers( public @Nullable List getViewManagerNames() { Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerNames"); - ReactApplicationContext context; - synchronized (mReactContextLock) { - context = (ReactApplicationContext) getCurrentReactContext(); - if (context == null || !context.hasActiveCatalystInstance()) { - return null; + if (mViewManagerNames == null) { + ReactApplicationContext context; + synchronized (mReactContextLock) { + context = (ReactApplicationContext) getCurrentReactContext(); + if (context == null || !context.hasActiveCatalystInstance()) { + return null; + } } - } - synchronized (mPackages) { - Set uniqueNames = new HashSet<>(); - for (ReactPackage reactPackage : mPackages) { - SystraceMessage.beginSection( - TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName") - .arg("Package", reactPackage.getClass().getSimpleName()) - .flush(); - if (reactPackage instanceof ViewManagerOnDemandReactPackage) { - List names = - ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context); - if (names != null) { - uniqueNames.addAll(names); + synchronized (mPackages) { + if (mViewManagerNames == null) { + Set uniqueNames = new HashSet<>(); + for (ReactPackage reactPackage : mPackages) { + SystraceMessage.beginSection( + TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName") + .arg("Package", reactPackage.getClass().getSimpleName()) + .flush(); + if (reactPackage instanceof ViewManagerOnDemandReactPackage) { + List names = + ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context); + if (names != null) { + uniqueNames.addAll(names); + } + } + SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush(); } + Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); + mViewManagerNames = new ArrayList<>(uniqueNames); } - SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush(); } - Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); - return new ArrayList<>(uniqueNames); } + return new ArrayList<>(mViewManagerNames); } /** Add a listener to be notified of react instance events. */ From 5772c4947d574a1cf3dad9de9c02c7edca68bb3e Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Mon, 1 Mar 2021 18:10:19 -0800 Subject: [PATCH 39/51] Fix failing CircleCI test for touch event timestamp Summary: Timestamp is computed differently now and uses system millis as the basis for a monotonic clock. Updating this fixes tests. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D26739611 fbshipit-source-id: 4908da68e1c126ea2b0772aaf408d892798549aa --- ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java index 9696e9a8069a9a..43a4558dd7fb52 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java @@ -115,7 +115,7 @@ public void testTouchEmitter() { rootView.startReactApplication(instanceManager, ""); rootView.simulateAttachForTesting(); - long ts = SystemClock.uptimeMillis(); + long ts = SystemClock.currentTimeMillis(); // Test ACTION_DOWN event rootView.onTouchEvent(MotionEvent.obtain(100, ts, MotionEvent.ACTION_DOWN, 0, 0, 0)); From 3e1d7da9c1e33ef6e238adb071c9a536fc77bccf Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 1 Mar 2021 20:45:04 -0800 Subject: [PATCH 40/51] Guard .asObject calls with .isObject check in JSIExecutor Summary: When we call JSIExecutor::nativeCallSyncHook, we assume that the third argument is an object and call Value::asObject on it, before checking if the Object is an Array. Calling Value::asObject throws an error if the Value isn't an Object. This diff includes an isObject check on the third argument. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D26735262 fbshipit-source-id: 96eb43d6c8bc1d78f3b5e0dc24ed6d419a446ecf --- ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp index f490891446060f..f1d4c5170604cf 100644 --- a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp +++ b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp @@ -439,7 +439,7 @@ Value JSIExecutor::nativeCallSyncHook(const Value *args, size_t count) { throw std::invalid_argument("nativeCallSyncHook arg count must be 3"); } - if (!args[2].asObject(*runtime_).isArray(*runtime_)) { + if (!args[2].isObject() || !args[2].asObject(*runtime_).isArray(*runtime_)) { throw std::invalid_argument( folly::to("method parameters should be array")); } From f9a7d3aaa8a82fe567012037f83879af854a7b7c Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 1 Mar 2021 20:45:04 -0800 Subject: [PATCH 41/51] Guard .asObject calls with .isObject check in JSINativeModules Summary: Checking if the moduleInfo is null, before calling moduleInfo.asObject isn't sufficient. Before calling moduleInfo.asObject, we should first check if the moduleInfo is an Object. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D26735367 fbshipit-source-id: b726216857bf23a3c9bab14414bf45b10900e033 --- ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp b/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp index e7c56c206a5f26..0bf27d402e9eec 100644 --- a/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp +++ b/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp @@ -89,6 +89,8 @@ folly::Optional JSINativeModules::createModule( valueFromDynamic(rt, result->config), static_cast(result->index)); CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null"; + CHECK(moduleInfo.isObject()) + << "Module returned from genNativeModule isn't an Object"; folly::Optional module( moduleInfo.asObject(rt).getPropertyAsObject(rt, "module")); From ce8440c77c3e310263894c3ae24e900054a19f34 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 2 Mar 2021 00:12:35 -0800 Subject: [PATCH 42/51] Noop ModuleRegistry::registerModules() when called no modules Summary: In T85279528, we're trying to add a RCTURLRequestHandler to the NativeModule system, when the NativeModule system is in an invalid state. This causes a crash. Longer term, this crash will go away when we delete the legacy NativeModule system. However, in the short term: 1. The parent of this diff (i.e: D26741053) ensures that all RCTURLRequestHandlers are TurboModule-compatible. This makes the modules std::vector passed into ModuleRegistry::resigerModules empty. 2. This diff makes ModuleRegistry::registerModules() noop when the modules std::vector is empty. In tandem, these two diffs should mitigate this crash, by making sure we don't execute the code that crashes. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26741417 fbshipit-source-id: fc4a09f6adcbdd6dbe197c9aa6a55af077bd818b --- ReactCommon/cxxreact/ModuleRegistry.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ReactCommon/cxxreact/ModuleRegistry.cpp b/ReactCommon/cxxreact/ModuleRegistry.cpp index da75bc5b5857f3..741d97073d36b6 100644 --- a/ReactCommon/cxxreact/ModuleRegistry.cpp +++ b/ReactCommon/cxxreact/ModuleRegistry.cpp @@ -48,6 +48,11 @@ void ModuleRegistry::updateModuleNamesFromIndex(size_t index) { void ModuleRegistry::registerModules( std::vector> modules) { SystraceSection s_("ModuleRegistry::registerModules"); + // Noop if there are no NativeModules to add + if (modules.empty()) { + return; + } + if (modules_.empty() && unknownModules_.empty()) { modules_ = std::move(modules); } else { From 62fcb4e22c879e11e090c30b2ee61f4e82ff1180 Mon Sep 17 00:00:00 2001 From: Sam Goldman Date: Tue, 2 Mar 2021 00:24:36 -0800 Subject: [PATCH 43/51] Fixed Flow typing of TextInput refs Summary: `React.ElementRef>` is an inexact object type, which can not be spread into an exact object type, as is happening here. This error is masked in types-first mode, but causes the instance type of this component to be `any`. In a future version of Flow, this issue will be fixed, so this change unblocks upgrading Flow. This change is likely to cause code using `TextInput` refs to find errors which were missed before. Changelog: [General][Fixed] - Fixed Flow typing of TextInput refs Reviewed By: yungsters Differential Revision: D26733314 fbshipit-source-id: 8aa26ce5b49357b279f76dd1767a17a9fb4dd4f1 --- Libraries/Lists/FlatList.js | 2 ++ Libraries/Renderer/shims/ReactNativeTypes.js | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Libraries/Lists/FlatList.js b/Libraries/Lists/FlatList.js index 19012b8c9e581e..540a865d70f1a1 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -373,6 +373,8 @@ class FlatList extends React.PureComponent, void> { | ?React.ElementRef | ?React.ElementRef { if (this._listRef) { + /* $FlowFixMe[incompatible-return] Suppresses errors found when fixing + * TextInput typing */ return this._listRef.getScrollRef(); } } diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 552b118556aaf0..3811bfa35ad91c 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -99,7 +99,7 @@ export type PartialViewConfig = $ReadOnly<{ validAttributes?: PartialAttributeConfiguration, }>; -export type NativeMethods = { +export type NativeMethods = {| blur(): void, focus(): void, measure(callback: MeasureOnSuccessCallback): void, @@ -110,8 +110,7 @@ export type NativeMethods = { onFail?: () => void, ): void, setNativeProps(nativeProps: {...}): void, - ... -}; +|}; export type HostComponent = AbstractComponent>; From dec1b6ba15df8f255d30b696a7c08ef543d1d19c Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Tue, 2 Mar 2021 10:41:20 -0800 Subject: [PATCH 44/51] Test setting layout params to wrap_content for fix text layout bug Summary: Changelog: [Android][Fixed] - Fix layout bug in ReactTextView. Reviewed By: mdvacca Differential Revision: D26752392 fbshipit-source-id: eeb9c16a4165b4d9329534981925621ae51a7dcb --- .../facebook/react/views/text/ReactTextView.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 85e5cdd62e8954..11dabebc61fb7d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -48,6 +48,10 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie private static final ViewGroup.LayoutParams EMPTY_LAYOUT_PARAMS = new ViewGroup.LayoutParams(0, 0); + private static final ViewGroup.LayoutParams WRAP_CONTENT_LAYOUT_PARAMS = + new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + private boolean mContainsImages; private int mDefaultGravityHorizontal; private int mDefaultGravityVertical; @@ -266,12 +270,14 @@ public int compare(Object o1, Object o2) { public void setText(ReactTextUpdate update) { mContainsImages = update.containsImages(); - if (ReactFeatureFlags.enableSettingEmptyLayoutParams) { - // Android's TextView crashes when it tries to relayout if LayoutParams are - // null; explicitly set the LayoutParams to prevent this crash. See: - // https://github.com/facebook/react-native/pull/7011 - if (getLayoutParams() == null) { + // Android's TextView crashes when it tries to relayout if LayoutParams are + // null; explicitly set the LayoutParams to prevent this crash. See: + // https://github.com/facebook/react-native/pull/7011 + if (getLayoutParams() == null) { + if (ReactFeatureFlags.enableSettingEmptyLayoutParams) { setLayoutParams(EMPTY_LAYOUT_PARAMS); + } else { + setLayoutParams(WRAP_CONTENT_LAYOUT_PARAMS); } } Spannable spannable = update.getText(); From caa5abc819bca751ad8a61718d163d63c82b59b4 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 2 Mar 2021 11:04:17 -0800 Subject: [PATCH 45/51] Remove unnecessary dependency from react buck module Summary: This diff removes an unnecessary dependency from react buck module This was causing a regression in apk size in IG changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26755329 fbshipit-source-id: bc45d9717bb0343cd26ed2ccbaa016b55f56b9bf --- ReactAndroid/src/main/java/com/facebook/react/BUCK | 1 - 1 file changed, 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index 6019f3f39f8ac7..6f76ec6ff501fc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -30,7 +30,6 @@ rn_android_library( react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/devsupport:devsupport"), react_native_target("java/com/facebook/react/devsupport:interfaces"), - react_native_target("java/com/facebook/react/fabric:fabric"), react_native_target("java/com/facebook/react/jscexecutor:jscexecutor"), react_native_target("java/com/facebook/react/jstasks:jstasks"), react_native_target("java/com/facebook/react/module/annotations:annotations"), From cbe7c445f7a065ec7b79717e6f7bd2dfda06f62f Mon Sep 17 00:00:00 2001 From: Andrei Shikov Date: Tue, 2 Mar 2021 13:49:32 -0800 Subject: [PATCH 46/51] Add logging to ReactModalHostView Summary: Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D26752344 fbshipit-source-id: 0cc7987e553896144fadcc8ede8f37f74b4b5bc5 --- .../main/java/com/facebook/react/views/modal/BUCK | 1 + .../react/views/modal/ReactModalHostView.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK index 73cedfd484bba5..20c442aef6ebee 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK @@ -17,6 +17,7 @@ rn_android_library( YOGA_TARGET, react_native_dep("third-party/java/infer-annotations:infer-annotations"), react_native_dep("third-party/java/jsr-305:jsr-305"), + react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"), react_native_root_target("Libraries:generated_components_java-FBReactNativeComponentSpec"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/common:common"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java index db03bfac47ad45..32d04e36b453e2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java @@ -23,6 +23,7 @@ import android.widget.FrameLayout; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.R; import com.facebook.react.bridge.GuardedRunnable; @@ -61,6 +62,8 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListener, FabricViewStateManager.HasFabricViewStateManager { + private static final String TAG = "ReactModalHost"; + // This listener is called when the user presses KeyEvent.KEYCODE_BACK // An event is then passed to JS which can either close or not close the Modal by setting the // visible property @@ -244,6 +247,15 @@ protected void showOrUpdate() { // If the existing Dialog is currently up, we may need to redraw it or we may be able to update // the property without having to recreate the dialog if (mDialog != null) { + Context dialogContext = ContextUtils.findContextOfType(mDialog.getContext(), Activity.class); + // TODO(T85755791): remove after investigation + FLog.e( + TAG, + "Updating existing dialog with context: " + + dialogContext + + "@" + + dialogContext.hashCode()); + if (mPropertyRequiresNewDialog) { dismiss(); } else { @@ -269,6 +281,9 @@ protected void showOrUpdate() { WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + // TODO(T85755791): remove after investigation + FLog.e(TAG, "Creating new dialog from context: " + context + "@" + context.hashCode()); + mDialog.setContentView(getContentView()); updateProperties(); From be7f057baccaa98ad40cbf8abe59a387c30ee19b Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Tue, 2 Mar 2021 16:26:21 -0800 Subject: [PATCH 47/51] Try reduce flackiness of VeniceTest Summary: Simplify addLifecycleEventListener for the flaky test because we just want to test that listener is working. Changelog: [Android][Changed] - Add a spare implementation of addLifecycleEventListener for test purpose. Reviewed By: PeteTheHeat Differential Revision: D26749256 fbshipit-source-id: 5af216e6bfa37a15eb189aa24a3df35a7a7112de --- .../main/java/com/facebook/react/bridge/ReactContext.java | 8 +++++++- .../java/com/facebook/react/fabric/FabricUIManager.java | 4 ++-- .../com/facebook/react/modules/core/TimingModule.java | 2 +- .../react/modules/deviceinfo/DeviceInfoModule.java | 2 +- .../com/facebook/react/uimanager/ThemedReactContext.java | 4 ++-- .../com/facebook/react/uimanager/UIManagerModule.java | 4 ++-- .../react/uimanager/events/EventDispatcherImpl.java | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index 28d024fd4b002b..30d2de3f2f29dc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -23,6 +23,7 @@ import com.facebook.react.bridge.queue.ReactQueueConfiguration; import com.facebook.react.common.LifecycleState; import com.facebook.react.common.ReactConstants; +import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.config.ReactFeatureFlags; import java.lang.ref.WeakReference; import java.util.concurrent.CopyOnWriteArraySet; @@ -182,9 +183,14 @@ public LifecycleState getLifecycleState() { return mLifecycleState; } + @VisibleForTesting public void addLifecycleEventListener(final LifecycleEventListener listener) { mLifecycleEventListeners.add(listener); - if (hasActiveCatalystInstance() || isBridgeless()) { + } + + public void addLifecycleEventListenerAndCheckState(final LifecycleEventListener listener) { + mLifecycleEventListeners.add(listener); + if (hasActiveCatalystInstance()) { switch (mLifecycleState) { case BEFORE_CREATE: case BEFORE_RESUME: diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 08cd93b133e9f3..e05d0d8c830aa6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -176,7 +176,7 @@ public FabricUIManager( mEventDispatcher = eventDispatcher; mShouldDeallocateEventDispatcher = false; mEventBeatManager = eventBeatManager; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } public FabricUIManager( @@ -189,7 +189,7 @@ public FabricUIManager( mEventDispatcher = new EventDispatcherImpl(reactContext); mShouldDeallocateEventDispatcher = true; mEventBeatManager = eventBeatManager; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } // TODO (T47819352): Rename this to startSurface for consistency with xplat/iOS diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java index 8ac7f07606a4a0..5abe37b3a5a23f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java @@ -68,7 +68,7 @@ public TimingModule(ReactApplicationContext reactContext, DevSupportManager devS @Override public void initialize() { - getReactApplicationContext().addLifecycleEventListener(this); + getReactApplicationContext().addLifecycleEventListenerAndCheckState(this); HeadlessJsTaskContext headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext()); headlessJsTaskContext.addTaskEventListener(this); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java index 083c9c1d9f27b1..2de4acce4ef862 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java @@ -37,7 +37,7 @@ public DeviceInfoModule(ReactApplicationContext reactContext) { DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); mFontScale = reactContext.getResources().getConfiguration().fontScale; mReactApplicationContext = reactContext; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } public DeviceInfoModule(Context context) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java index 15701d63618a40..2e1493f3f437f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java @@ -56,8 +56,8 @@ public ThemedReactContext( } @Override - public void addLifecycleEventListener(LifecycleEventListener listener) { - mReactApplicationContext.addLifecycleEventListener(listener); + public void addLifecycleEventListenerAndCheckState(LifecycleEventListener listener) { + mReactApplicationContext.addLifecycleEventListenerAndCheckState(listener); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 1d49251377d546..182c04fb84077d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -158,7 +158,7 @@ public UIManagerModule( mEventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); - reactContext.addLifecycleEventListener(this); + reactContext.addLifecycleEventListenerAndCheckState(this); } @Deprecated @@ -180,7 +180,7 @@ public UIManagerModule( mEventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); - reactContext.addLifecycleEventListener(this); + reactContext.addLifecycleEventListenerAndCheckState(this); } /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java index a99d6b1eb31699..8e3ded74b1d13d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java @@ -104,7 +104,7 @@ public int compare(Event lhs, Event rhs) { public EventDispatcherImpl(ReactApplicationContext reactContext) { mReactContext = reactContext; - mReactContext.addLifecycleEventListener(this); + mReactContext.addLifecycleEventListenerAndCheckState(this); mReactEventEmitter = new ReactEventEmitter(mReactContext); } From 6ccd0cdebb2be335eaed93563ec9ed84677f9484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 2 Mar 2021 16:38:23 -0800 Subject: [PATCH 48/51] Bump Android compileSdkVersion and targetSdkVersion to 30 (#31078) Summary: ## Summary Bump Android compileSdkVersion and targetSdkVersion to 30 ## Changelog [Android][Changed] Bump Android compileSdkVersion and targetSdkVersion from 29 to 30 Pull Request resolved: https://github.com/facebook/react-native/pull/31078 Test Plan: Circle CI and Sandcastle Reviewed By: mdvacca Differential Revision: D26765188 Pulled By: hramos fbshipit-source-id: a971641cea4860df58ce6e9b0f14405bfc4e0979 --- .buckconfig | 2 +- .circleci/Dockerfiles/Dockerfile.android | 2 +- .circleci/config.yml | 4 ++-- ReactAndroid/build.gradle | 2 +- package.json | 2 +- template/android/build.gradle | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.buckconfig b/.buckconfig index 0740647479601e..3d98e74d71e06a 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,6 +1,6 @@ [android] - target = android-29 + target = android-30 [download] max_number_of_retries = 3 diff --git a/.circleci/Dockerfiles/Dockerfile.android b/.circleci/Dockerfiles/Dockerfile.android index 5b313b53bfa679..92bf645af1d260 100644 --- a/.circleci/Dockerfiles/Dockerfile.android +++ b/.circleci/Dockerfiles/Dockerfile.android @@ -14,7 +14,7 @@ # and build a Android application that can be used to run the # tests specified in the scripts/ directory. # -FROM reactnativecommunity/react-native-android:2.1 +FROM reactnativecommunity/react-native-android:3.2 LABEL Description="React Native Android Test Image" LABEL maintainer="Héctor Ramos " diff --git a/.circleci/config.yml b/.circleci/config.yml index ca3e88fc57bad4..dc1337a2e107e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,7 +35,7 @@ executors: reactnativeandroid: <<: *defaults docker: - - image: reactnativecommunity/react-native-android:2.1 + - image: reactnativecommunity/react-native-android:3.2 resource_class: "large" environment: - TERM: "dumb" @@ -617,7 +617,7 @@ jobs: environment: - ANDROID_HOME: "C:\\Android\\android-sdk" - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944" - - ANDROID_BUILD_VERSION: 28 + - ANDROID_BUILD_VERSION: 30 - ANDROID_TOOLS_VERSION: 29.0.3 - GRADLE_OPTS: -Dorg.gradle.daemon=false - NDK_VERSION: 20.1.5948944 diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 8b8a05d29e4738..0944a54a9bab74 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -378,7 +378,7 @@ task extractJNIFiles { } android { - compileSdkVersion 29 + compileSdkVersion 30 ndkVersion ANDROID_NDK_VERSION compileOptions { sourceCompatibility(JavaVersion.VERSION_1_8) diff --git a/package.json b/package.json index b3e149b7080a26..0a415efadd3699 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "prettier": "prettier --write \"./**/*.{js,md,yml}\"", "format-check": "prettier --list-different \"./**/*.{js,md,yml}\"", "update-lock": "npx yarn-deduplicate", - "docker-setup-android": "docker pull reactnativecommunity/react-native-android:2.1", + "docker-setup-android": "docker pull reactnativecommunity/react-native-android:3.2", "docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .", "test-android-run-instrumentation": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh", "test-android-run-unit": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh", diff --git a/template/android/build.gradle b/template/android/build.gradle index 93232f5fca9389..ac4d64714c0bfb 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -4,8 +4,8 @@ buildscript { ext { buildToolsVersion = "29.0.3" minSdkVersion = 21 - compileSdkVersion = 29 - targetSdkVersion = 29 + compileSdkVersion = 30 + targetSdkVersion = 30 ndkVersion = "20.1.5948944" } repositories { From 397bfa6ad7dff71f4b6d27ac17acc76fe8a6bbb5 Mon Sep 17 00:00:00 2001 From: Nadiia D Date: Tue, 2 Mar 2021 18:01:53 -0800 Subject: [PATCH 49/51] Hide caret during test runs Summary: Changelog: [General][Changed] Hide caret in the TextInput during test runs. Reviewed By: lunaleaps Differential Revision: D26728766 fbshipit-source-id: b75827f00b4d5c6243d93106093f97b40dc4b366 --- Libraries/Components/TextInput/TextInput.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 39967a67111649..646e7d981a1ecf 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -1083,6 +1083,13 @@ function InternalTextInput(props: Props): React.Node { ], ); + // Hide caret during test runs due to a flashing caret + // makes screenshot tests flakey + let caretHidden = props.caretHidden; + if (Platform.isTesting) { + caretHidden = true; + } + // TextInput handles onBlur and onFocus events // so omitting onBlur and onFocus pressability handlers here. const {onBlur, onFocus, ...eventHandlers} = usePressability(config) || {}; @@ -1105,6 +1112,7 @@ function InternalTextInput(props: Props): React.Node { {...eventHandlers} accessible={accessible} blurOnSubmit={blurOnSubmit} + caretHidden={caretHidden} dataDetectorTypes={props.dataDetectorTypes} focusable={focusable} mostRecentEventCount={mostRecentEventCount} @@ -1143,6 +1151,7 @@ function InternalTextInput(props: Props): React.Node { accessible={accessible} autoCapitalize={autoCapitalize} blurOnSubmit={blurOnSubmit} + caretHidden={caretHidden} children={children} disableFullscreenUI={props.disableFullscreenUI} focusable={focusable} From ede065c8b06ff7b0fb5fdb659cb85ca01f76bd3c Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Wed, 3 Mar 2021 01:07:45 -0800 Subject: [PATCH 50/51] SectionList example add updateProps to example Summary: # Changelog [General][Added] - Expand example in RNTester for separators on VirtualizedSectionList to showcase updating props on separator ("has not been pressed" -> "has been pressed") Reviewed By: nadiia, kacieb Differential Revision: D26713429 fbshipit-source-id: 21034fab5a80d46c46462c41b0989cc9e4c45d03 --- .../SectionList/SectionListExamples.js | 71 +++++++++++-------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js index 6eb9eb4c2dc8ea..df68a5209f41fe 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js @@ -46,8 +46,16 @@ const VIEWABILITY_CONFIG = { const Item = ({item, section, separators}) => { return ( { + separators.highlight(); + }} + onPress={() => { + separators.updateProps('trailing', {hasBeenHighlighted: true}); + separators.updateProps('leading', {hasBeenHighlighted: true}); + }} + onPressOut={() => { + separators.unhighlight(); + }} style={({pressed}) => [ styles.item, { @@ -60,7 +68,18 @@ const Item = ({item, section, separators}) => { ); }; -const Separator = (defaultColor, highlightColor, text) => ({highlighted}) => { +const Separator = (defaultColor, highlightColor, isSectionSeparator) => ({ + leadingItem, + trailingItem, + highlighted, + hasBeenHighlighted, +}) => { + const text = `${ + isSectionSeparator ? 'Section ' : '' + }separator for leading ${leadingItem} and trailing ${trailingItem} has ${ + !hasBeenHighlighted ? 'not ' : '' + }been pressed`; + return ( >(); - const onTest = null; - return ( - + ); } @@ -232,7 +240,6 @@ export function SectionList_onViewableItemsChanged(): React.Node { return ( ); @@ -242,7 +249,7 @@ type Props = { exampleProps: $Shape>, onTest?: ?() => void, testLabel?: ?string, - testOutput: ?string, + testOutput?: ?string, }; const SectionListExampleWithForwardedRef = React.forwardRef( @@ -252,18 +259,20 @@ const SectionListExampleWithForwardedRef = React.forwardRef( ): React.Node { return ( - - - {props.testOutput} - - {props.onTest != null ? ( -